fcl-passrc: optional parse units queued instead of recursively

git-svn-id: trunk@38414 -
This commit is contained in:
Mattias Gaertner 2018-03-05 20:58:04 +00:00
parent 77b97abe61
commit d34e9b79bf
5 changed files with 263 additions and 69 deletions

View File

@ -665,6 +665,7 @@ type
Data: Pointer; var Abort: boolean);
public
UsesScopes: TFPList; // list of TPasSectionScope
UsesFinished: boolean;
Finished: boolean;
constructor Create; override;
destructor Destroy; override;
@ -1434,8 +1435,9 @@ type
function GetVisibilityContext: TPasElement;
procedure FinishScope(ScopeType: TPasScopeType; El: TPasElement); override;
function IsUnitIntfFinished(AModule: TPasModule): boolean;
procedure NotifyPendingUsedInterfaces; virtual;
function GetPendingUsedInterface(Section: TPasSection): TPasUsesUnit;
procedure CheckPendingUsedInterface(Section: TPasSection); override;
function CheckPendingUsedInterface(Section: TPasSection): boolean; override;
procedure ContinueParsing; virtual;
function NeedArrayValues(El: TPasElement): boolean; override;
function GetDefaultClassVisibility(AClass: TPasClassType
@ -4045,6 +4047,10 @@ begin
{$IFDEF VerbosePasResolver}
writeln('TPasResolver.FinishUsesClause Section=',Section.ClassName,' Section.UsesList.Count=',Section.UsesList.Count);
{$ENDIF}
if Scope.UsesFinished then
RaiseInternalError(20180305145220);
Scope.UsesFinished:=true;
for i:=0 to Section.UsesList.Count-1 do
begin
UseUnit:=Section.UsesClause[i];
@ -4055,8 +4061,8 @@ begin
// check used unit
PublicEl:=nil;
if (UseModule.ClassType=TLibrarySection) then
PublicEl:=UseModule
if (UseModule.ClassType=TPasLibrary) then
PublicEl:=TPasLibrary(UseModule).LibrarySection
else if (UseModule.ClassType=TPasModule) then
PublicEl:=TPasModule(UseModule).InterfaceSection
else
@ -4131,29 +4137,12 @@ begin
end;
procedure TPasResolver.FinishInterfaceSection(Section: TPasSection);
var
ModuleScope: TPasModuleScope;
PendingResolver: TPasResolver;
PendingParser: TPasParser;
PendingModule: TPasModule;
PendingImpl: TImplementationSection;
begin
{$IFDEF VerbosePasResolver}
if not IsUnitIntfFinished(Section.GetModule) then
RaiseInternalError(20171214004323,'TPasResolver.FinishInterfaceSection "'+CurrentParser.CurModule.Name+'" "'+Section.GetModule.Name+'" IsUnitIntfFinished=false');
{$ENDIF}
ModuleScope:=CurrentParser.CurModule.CustomData as TPasModuleScope;
while ModuleScope.PendingResolvers.Count>0 do
begin
PendingResolver:=TObject(ModuleScope.PendingResolvers[0]) as TPasResolver;
PendingParser:=PendingResolver.CurrentParser;
PendingModule:=PendingParser.CurModule;
PendingImpl:=PendingModule.ImplementationSection;
{$IFDEF VerbosePasResolver}
writeln('TPasResolver.FinishInterfaceSection "',ModuleScope.Element.Name,'" Pending="',PendingModule.Name,'"');
{$ENDIF}
PendingResolver.CheckPendingUsedInterface(PendingImpl);
end;
NotifyPendingUsedInterfaces;
if Section=nil then ;
end;
@ -11835,6 +11824,45 @@ begin
and TPasSectionScope(CurIntf.CustomData).Finished;
end;
procedure TPasResolver.NotifyPendingUsedInterfaces;
// called after unit interface is ready to be used by other modules
var
ModuleScope: TPasModuleScope;
i: Integer;
PendingResolver: TPasResolver;
PendingParser: TPasParser;
PendingSection: TPasSection;
Changed: Boolean;
begin
// call all PendingResolvers
// Note that a waiting resolver might continue parsing, so this
// recursively solves all unit cycles
ModuleScope:=RootElement.CustomData as TPasModuleScope;
i:=ModuleScope.PendingResolvers.Count-1;
while i>=0 do
begin
PendingResolver:=TObject(ModuleScope.PendingResolvers[i]) as TPasResolver;
PendingParser:=PendingResolver.CurrentParser;
PendingSection:=PendingParser.GetLastSection;
{$IFDEF VerbosePasResolver}
writeln('TPasResolver.FinishInterfaceSection "',ModuleScope.Element.Name,'" Pending="',PendingResolver.RootElement.Name,'"');
{$ENDIF}
if PendingSection=nil then
RaiseInternalError(20180305141421);
Changed:=PendingResolver.CheckPendingUsedInterface(PendingSection); // beware: this might alter the ModuleScope.PendingResolvers
if Changed and (PendingSection.PendingUsedIntf=nil) then
begin
{$IFDEF VerbosePasResolver}
writeln('TPasResolver.FinishInterfaceSection "',ModuleScope.Element.Name,'" Continue="',PendingResolver.RootElement.Name,'"');
{$ENDIF}
PendingParser.ParseContinue;
end;
dec(i);
if i>=ModuleScope.PendingResolvers.Count then
i:=ModuleScope.PendingResolvers.Count-1;
end;
end;
function TPasResolver.GetPendingUsedInterface(Section: TPasSection
): TPasUsesUnit;
var
@ -11842,7 +11870,6 @@ var
UseUnit: TPasUsesUnit;
begin
Result:=nil;
if not (Section is TImplementationSection) then exit;
for i:=0 to length(Section.UsesClause)-1 do
begin
UseUnit:=Section.UsesClause[i];
@ -11852,7 +11879,7 @@ begin
end;
end;
procedure TPasResolver.CheckPendingUsedInterface(Section: TPasSection);
function TPasResolver.CheckPendingUsedInterface(Section: TPasSection): boolean;
var
PendingModule: TPasModule;
PendingModuleScope: TPasModuleScope;
@ -11860,7 +11887,7 @@ var
WasPending: Boolean;
begin
{$IFDEF VerbosePasResolver}
//writeln('TPasResolver.CheckPendingUsedInterface START "',CurrentParser.CurModule.Name,'"');
//writeln('TPasResolver.CheckPendingUsedInterface START "',CurrentParser.CurModule.Name,'" Section.PendingUsedIntf=',Section.PendingUsedIntf<>nil);
{$ENDIF}
WasPending:=Section.PendingUsedIntf<>nil;
if WasPending then
@ -11869,6 +11896,9 @@ begin
if not IsUnitIntfFinished(PendingModule) then
exit; // still pending
// other unit interface is finished
{$IFDEF VerbosePasResolver}
writeln('TPasResolver.CheckPendingUsedInterface "',CurrentParser.CurModule.Name,'" UnitIntf finished of "',PendingModule.Name,'"');
{$ENDIF}
PendingModuleScope:=NoNil(PendingModule.CustomData) as TPasModuleScope;
PendingModuleScope.PendingResolvers.Remove(Self);
Section.PendingUsedIntf:=nil;
@ -11877,7 +11907,7 @@ begin
Section.PendingUsedIntf:=GetPendingUsedInterface(Section);
if Section.PendingUsedIntf<>nil then
begin
// unit not yet finished due to pending used interfaces
// module not yet finished due to pending used interfaces
PendingModule:=Section.PendingUsedIntf.Module as TPasModule;
PendingModuleScope:=NoNil(PendingModule.CustomData) as TPasModuleScope;
{$IFDEF VerbosePasResolver}
@ -11886,12 +11916,16 @@ begin
List:=PendingModuleScope.PendingResolvers;
if List.IndexOf(Self)<0 then
List.Add(Self);
Result:=not WasPending;
end
else
begin
{$IFDEF VerbosePasResolver}
if WasPending then
// can now continue parsing
ContinueParsing;
writeln('TPasResolver.CheckPendingUsedInterface "',CurrentParser.CurModule.Name,'" uses section complete: ',Section.ClassName);
{$ENDIF}
Result:=WasPending;
end;
end;
@ -11902,7 +11936,7 @@ begin
{$IFDEF VerbosePasResolver}
writeln('TPasResolver.ContinueParsing "',CurrentParser.CurModule.Name,'"...');
{$ENDIF}
CurrentParser.ParseContinueImplementation;
CurrentParser.ParseContinue;
end;
function TPasResolver.NeedArrayValues(El: TPasElement): boolean;

View File

@ -192,7 +192,7 @@ type
procedure FinishScope(ScopeType: TPasScopeType; El: TPasElement); virtual;
function FindModule(const AName: String): TPasModule; virtual;
function FindModule(const AName: String; NameExpr, InFileExpr: TPasExpr): TPasModule; virtual;
procedure CheckPendingUsedInterface(Section: TPasSection); virtual;
function CheckPendingUsedInterface(Section: TPasSection): boolean; virtual; // true if changed
function NeedArrayValues(El: TPasElement): boolean; virtual;
function GetDefaultClassVisibility(AClass: TPasClassType): TPasMemberVisibility; virtual;
property Package: TPasPackage read FPackage;
@ -401,7 +401,9 @@ type
// Main scope parsing
procedure ParseMain(var Module: TPasModule);
procedure ParseUnit(var Module: TPasModule);
procedure ParseContinueImplementation;
function GetLastSection: TPasSection; virtual;
function CanParseContinue(out Section: TPasSection): boolean; virtual;
procedure ParseContinue; virtual;
procedure ParseProgram(var Module: TPasModule; SkipHeader : Boolean = False);
procedure ParseLibrary(var Module: TPasModule);
procedure ParseOptionalUsesList(ASection: TPasSection);
@ -778,9 +780,11 @@ begin
if InFileExpr=nil then ;
end;
procedure TPasTreeContainer.CheckPendingUsedInterface(Section: TPasSection);
function TPasTreeContainer.CheckPendingUsedInterface(Section: TPasSection
): boolean;
begin
if Section=nil then ; // avoid compiler warning
Result:=false;
end;
function TPasTreeContainer.NeedArrayValues(El: TPasElement): boolean;
@ -2727,39 +2731,137 @@ begin
end;
CheckHint(Module,True);
ExpectToken(tkInterface);
If LogEvent(pleInterface) then
DoLog(mtInfo,nLogStartInterface,SLogStartInterface);
if po_StopOnUnitInterface in Options then
begin
HasFinished:=false;
{$IFDEF VerbosePasResolver}
writeln('TPasParser.ParseUnit pause parsing after unit name ',CurModule.Name);
{$ENDIF}
exit;
end;
ParseInterface;
if (Module.InterfaceSection<>nil)
and (Module.InterfaceSection.PendingUsedIntf<>nil) then
begin
HasFinished:=false;
{$IFDEF VerbosePasResolver}
writeln('TPasParser.ParseUnit pause parsing after interface uses list ',CurModule.Name);
{$ENDIF}
end;
if (Module.ImplementationSection<>nil)
and (Module.ImplementationSection.PendingUsedIntf<>nil) then
begin
HasFinished:=false;
{$IFDEF VerbosePasResolver}
writeln('TPasParser.ParseUnit pause parsing after implementation uses list ',CurModule.Name);
{$ENDIF}
end;
if HasFinished then
Engine.FinishScope(stModule,Module);
finally
if HasFinished then
FCurModule:=nil;
FCurModule:=nil; // clear module if there is an error or finished parsing
end;
end;
procedure TPasParser.ParseContinueImplementation;
function TPasParser.GetLastSection: TPasSection;
begin
Result:=nil;
if FCurModule=nil then
exit; // parse completed
if CurModule is TPasProgram then
Result:=TPasProgram(CurModule).ProgramSection
else if CurModule is TPasLibrary then
Result:=TPasLibrary(CurModule).LibrarySection
else if (CurModule.ClassType=TPasModule) or (CurModule is TPasUnitModule) then
begin
if CurModule.ImplementationSection<>nil then
Result:=CurModule.ImplementationSection
else
Result:=CurModule.InterfaceSection; // might be nil
end;
end;
function TPasParser.CanParseContinue(out Section: TPasSection): boolean;
begin
Result:=false;
Section:=nil;
if FCurModule=nil then
exit; // parse completed
if (LastMsg<>'') and (LastMsgType<=mtError) then
begin
{$IFDEF VerbosePasResolver}
writeln('TPasParser.CanParseContinue ',CurModule.Name,' LastMsg="',LastMsgType,':',LastMsg,'"');
{$ENDIF}
exit;
end;
if (Scanner.LastMsg<>'') and (Scanner.LastMsgType<=mtError) then
begin
{$IFDEF VerbosePasResolver}
writeln('TPasParser.CanParseContinue ',CurModule.Name,' Scanner.LastMsg="',Scanner.LastMsgType,':',Scanner.LastMsg,'"');
{$ENDIF}
exit;
end;
Section:=GetLastSection;
if Section=nil then
if (po_StopOnUnitInterface in Options)
and ((CurModule is TPasUnitModule) or (CurModule.ClassType=TPasModule))
and (CurModule.InterfaceSection=nil) then
exit(true)
else
exit(false);
Result:=Section.PendingUsedIntf=nil;
end;
procedure TPasParser.ParseContinue;
// continue parsing after stopped due to pending uses
var
Section: TPasSection;
HasFinished: Boolean;
begin
if CurModule=nil then
ParseExcTokenError('TPasParser.ParseContinue missing module');
{$IFDEF VerbosePasParser}
writeln('TPasParser.ParseContinue ',CurModule.Name);
{$ENDIF}
if not CanParseContinue(Section) then
ParseExcTokenError('TPasParser.ParseContinue missing section');
HasFinished:=true;
try
ParseDeclarations(CurModule.ImplementationSection);
Engine.FinishScope(stModule,CurModule);
if Section=nil then
begin
// continue after unit name
ParseInterface;
end
else
begin
// continue after uses clause
Engine.FinishScope(stUsesClause,Section);
ParseDeclarations(Section);
end;
Section:=GetLastSection;
if (Section<>nil) and (Section.PendingUsedIntf<>nil) then
HasFinished:=false;
if HasFinished then
Engine.FinishScope(stModule,CurModule);
finally
FCurModule:=nil;
if HasFinished then
FCurModule:=nil; // clear module if there is an error or finished parsing
end;
end;
// Starts after the "program" token
procedure TPasParser.ParseProgram(var Module: TPasModule; SkipHeader : Boolean = False);
Var
PP : TPasProgram;
Section : TProgramSection;
N : String;
StartPos: TPasSourcePos;
HasFinished: Boolean;
{$IFDEF VerbosePasResolver}
aSection: TPasSection;
{$ENDIF}
begin
StartPos:=CurTokenPos;
if SkipHeader then
@ -2779,6 +2881,7 @@ begin
Module := nil;
PP:=TPasProgram(CreateElement(TPasProgram, N, Engine.Package, StartPos));
Module :=PP;
HasFinished:=true;
FCurModule:=Module;
try
if Assigned(Engine.Package) then
@ -2806,10 +2909,26 @@ begin
Section := TProgramSection(CreateElement(TProgramSection, '', CurModule));
PP.ProgramSection := Section;
ParseOptionalUsesList(Section);
HasFinished:=Section.PendingUsedIntf=nil;
if not HasFinished then
begin
{$IFDEF VerbosePasResolver}
writeln('TPasParser.ParseProgram pause parsing after uses list of "',CurModule.Name,'"');
if CanParseContinue(aSection) then
begin
writeln('TPasParser.ParseProgram Section=',Section.ClassName,' Section.PendingUsedIntf=',Section.PendingUsedIntf<>nil);
if aSection<>nil then
writeln('TPasParser.ParseProgram aSection=',aSection.ClassName,' ',Section=aSection);
ParseExc(nErrNoSourceGiven,'[20180305172432] ');
end;
{$ENDIF}
exit;
end;
ParseDeclarations(Section);
Engine.FinishScope(stModule,Module);
finally
FCurModule:=nil;
if HasFinished then
FCurModule:=nil; // clear module if there is an error or finished parsing
end;
end;
@ -2820,6 +2939,7 @@ Var
Section : TLibrarySection;
N: String;
StartPos: TPasSourcePos;
HasFinished: Boolean;
begin
StartPos:=CurTokenPos;
@ -2835,6 +2955,7 @@ begin
Module := nil;
PP:=TPasLibrary(CreateElement(TPasLibrary, N, Engine.Package, StartPos));
Module :=PP;
HasFinished:=true;
FCurModule:=Module;
try
if Assigned(Engine.Package) then
@ -2848,10 +2969,14 @@ begin
Section := TLibrarySection(CreateElement(TLibrarySection, '', CurModule));
PP.LibrarySection := Section;
ParseOptionalUsesList(Section);
HasFinished:=Section.PendingUsedIntf=nil;
if not HasFinished then
exit;
ParseDeclarations(Section);
Engine.FinishScope(stModule,Module);
finally
FCurModule:=nil;
if HasFinished then
FCurModule:=nil; // clear module if there is an error or finished parsing
end;
end;
@ -2859,13 +2984,15 @@ procedure TPasParser.ParseOptionalUsesList(ASection: TPasSection);
// checks if next token is Uses keyword and reads the uses list
begin
NextToken;
CheckImplicitUsedUnits(ASection);
if CurToken=tkuses then
ParseUsesList(ASection)
else begin
CheckImplicitUsedUnits(ASection);
Engine.FinishScope(stUsesClause,ASection);
else
UngetToken;
end;
Engine.CheckPendingUsedInterface(ASection);
if ASection.PendingUsedIntf<>nil then
exit;
Engine.FinishScope(stUsesClause,ASection);
end;
// Starts after the "interface" token
@ -2873,9 +3000,13 @@ procedure TPasParser.ParseInterface;
var
Section: TInterfaceSection;
begin
If LogEvent(pleInterface) then
DoLog(mtInfo,nLogStartInterface,SLogStartInterface);
Section := TInterfaceSection(CreateElement(TInterfaceSection, '', CurModule));
CurModule.InterfaceSection := Section;
ParseOptionalUsesList(Section);
if Section.PendingUsedIntf<>nil then
exit;
ParseDeclarations(Section); // this also parses the Implementation section
end;
@ -2887,7 +3018,6 @@ begin
Section := TImplementationSection(CreateElement(TImplementationSection, '', CurModule));
CurModule.ImplementationSection := Section;
ParseOptionalUsesList(Section);
Engine.CheckPendingUsedInterface(Section);
if Section.PendingUsedIntf<>nil then
exit;
ParseDeclarations(Section);
@ -3412,8 +3542,6 @@ var
NamePos, SrcPos: TPasSourcePos;
aModule: TPasModule;
begin
CheckImplicitUsedUnits(ASection);
NameExpr:=nil;
InFileExpr:=nil;
FreeExpr:=true;
@ -3439,8 +3567,9 @@ begin
if (msDelphi in CurrentModeswitches) then
begin
aModule:=ASection.GetModule;
if (aModule<>nil) and ((aModule.ClassType=TPasModule) or (aModule is TPasUnitModule)) then
CheckToken(tkSemicolon); // delphi does not allow it in units
if (aModule<>nil)
and ((aModule.ClassType=TPasModule) or (aModule is TPasUnitModule)) then
CheckToken(tkSemicolon); // delphi does not allow in-filename in units
end;
ExpectToken(tkString);
InFileExpr:=CreatePrimitiveExpr(ASection,pekString,CurTokenString);
@ -3461,8 +3590,6 @@ begin
ReleaseAndNil(TPasElement(InFileExpr));
end;
end;
Engine.FinishScope(stUsesClause,ASection);
end;
// Starts after the variable name

View File

@ -558,10 +558,11 @@ type
po_KeepClassForward, // disabled: delete class fowards when there is a class declaration
po_ArrayRangeExpr, // enable: create TPasArrayType.IndexRange, disable: create TPasArrayType.Ranges
po_SelfToken, // Self is a token. For backward compatibility.
po_CheckModeSwitches, // stop on unknown modeswitch with an error
po_CheckCondFunction, // stop on unknown function in conditional expression, default: return '0'
po_StopOnErrorDirective, // stop on user $Error, $message error|fatal
po_ExtClassConstWithoutExpr // allow const without expression in external class
po_CheckModeSwitches, // error on unknown modeswitch with an error
po_CheckCondFunction, // error on unknown function in conditional expression, default: return '0'
po_StopOnErrorDirective, // error on user $Error, $message error|fatal
po_ExtClassConstWithoutExpr, // allow const without expression in external class
po_StopOnUnitInterface // parse only a unit name and stop at interface keyword
);
TPOptions = set of TPOption;

View File

@ -62,7 +62,7 @@ Type
Procedure Add(Const Lines : array of String);
Procedure StartParsing;
Procedure ParseDeclarations;
Procedure ParseModule;
Procedure ParseModule; virtual;
procedure ResetParser;
Procedure CheckHint(AHint : TPasMemberHint);
Function AssertExpression(Const Msg: String; AExpr : TPasExpr; aKind : TPasExprKind; AClass : TClass) : TPasExpr;

View File

@ -56,7 +56,6 @@ type
private
FFilename: string;
FModule: TPasModule;
FOnContinueParsing: TOnContinueParsing;
FOnFindUnit: TOnFindUnit;
FParser: TPasParser;
FStreamResolver: TStreamResolver;
@ -72,8 +71,6 @@ type
overload; override;
function FindUnit(const AName, InFilename: String; NameExpr,
InFileExpr: TPasExpr): TPasModule; override;
procedure ContinueParsing; override;
property OnContinueParsing: TOnContinueParsing read FOnContinueParsing write FOnContinueParsing;
property OnFindUnit: TOnFindUnit read FOnFindUnit write FOnFindUnit;
property Filename: string read FFilename write FFilename;
property StreamResolver: TStreamResolver read FStreamResolver write FStreamResolver;
@ -135,6 +132,7 @@ type
Procedure SetUp; override;
Procedure TearDown; override;
procedure CreateEngine(var TheEngine: TPasTreeContainer); override;
procedure ParseModule; override;
procedure ParseProgram; virtual;
procedure ParseUnit; virtual;
procedure CheckReferenceDirectives; virtual;
@ -777,11 +775,6 @@ begin
Result:=OnFindUnit(Self,AName,InFilename,NameExpr,InFileExpr);
end;
procedure TTestEnginePasResolver.ContinueParsing;
begin
OnContinueParsing(Self);
end;
{ TCustomTestResolver }
procedure TCustomTestResolver.SetUp;
@ -830,6 +823,45 @@ begin
TheEngine:=ResolverEngine;
end;
procedure TCustomTestResolver.ParseModule;
var
Section: TPasSection;
i: Integer;
CurResolver: TTestEnginePasResolver;
Found: Boolean;
begin
inherited ParseModule;
repeat
Found:=false;
for i:=0 to ModuleCount-1 do
begin
CurResolver:=Modules[i];
if CurResolver.Parser=nil then continue;
if CurResolver.Parser.CanParseContinue(Section) then
begin
{$IFDEF VerbosePasResolver}
writeln('TCustomTestResolver.ParseModule continue parsing section=',GetObjName(Section),' of ',CurResolver.Filename);
{$ENDIF}
Found:=true;
CurResolver.Parser.ParseContinue;
break;
end;
end;
until not Found;
for i:=0 to ModuleCount-1 do
begin
CurResolver:=Modules[i];
if CurResolver.CurrentParser.CurModule<>nil then
begin
{$IFDEF VerbosePasResolver}
writeln('TCustomTestResolver.ParseModule module not finished "',CurResolver.RootElement.Name,'"');
{$ENDIF}
Fail('module not finished "'+CurResolver.RootElement.Name+'"');
end;
end;
end;
procedure TCustomTestResolver.ParseProgram;
var
aFilename: String;
@ -1592,7 +1624,7 @@ begin
ErrFilename:=CurEngine.Scanner.CurFilename;
ErrRow:=CurEngine.Scanner.CurRow;
ErrCol:=CurEngine.Scanner.CurColumn;
writeln('ERROR: TTestResolver.OnPasResolverFindUnit during parsing: '+E.ClassName+':'+E.Message
writeln('ERROR: TCustomTestResolver.HandleError during parsing: '+E.ClassName+':'+E.Message
+' File='+ErrFilename
+' LineNo='+IntToStr(ErrRow)
+' Col='+IntToStr(ErrCol)
@ -1636,7 +1668,6 @@ begin
Result.Filename:=aFilename;
Result.AddObjFPCBuiltInIdentifiers;
Result.OnFindUnit:=@OnPasResolverFindUnit;
Result.OnContinueParsing:=@OnPasResolverContinueParsing;
Result.OnLog:=@OnPasResolverLog;
FModules.Add(Result);
end;
@ -1787,6 +1818,7 @@ function TCustomTestResolver.OnPasResolverFindUnit(SrcResolver: TPasResolver;
CurEngine.Scanner.CurrentBoolSwitches:=[bsHints,bsNotes,bsWarnings];
CurEngine.Parser:=TPasParser.Create(CurEngine.Scanner,
CurEngine.StreamResolver,CurEngine);
CurEngine.Parser.Options:=CurEngine.Parser.Options+[po_StopOnUnitInterface];
if CompareText(ExtractFileUnitName(CurEngine.Filename),'System')=0 then
CurEngine.Parser.ImplicitUses.Clear;
CurEngine.Scanner.OpenFile(CurEngine.Filename);
@ -2056,7 +2088,7 @@ begin
writeln('TCustomTestResolver.OnPasResolverContinueParsing "',CurEngine.Module.Name,'"...');
{$ENDIF}
try
CurEngine.Parser.ParseContinueImplementation;
CurEngine.Parser.ParseContinue;
except
on E: Exception do
HandleError(CurEngine,E);