accelerated parsing

git-svn-id: trunk@4119 -
This commit is contained in:
mattias 2003-05-02 08:11:37 +00:00
parent 750ad640fb
commit d69ad8c66e
3 changed files with 95 additions and 23 deletions

View File

@ -56,6 +56,7 @@ interface
{ $DEFINE ShowTriedContexts} { $DEFINE ShowTriedContexts}
{ $DEFINE ShowTriedParentContexts} { $DEFINE ShowTriedParentContexts}
{ $DEFINE ShowTriedIdentifiers} { $DEFINE ShowTriedIdentifiers}
{ $DEFINE ShowTriedUnits}
{ $DEFINE ShowExprEval} { $DEFINE ShowExprEval}
{ $DEFINE ShowFoundIdentifier} { $DEFINE ShowFoundIdentifier}
{ $DEFINE ShowInterfaceCache} { $DEFINE ShowInterfaceCache}
@ -188,9 +189,14 @@ type
fdfDoNotCache fdfDoNotCache
); );
TFoundDeclarationFlags = set of TFoundDeclarationFlag; TFoundDeclarationFlags = set of TFoundDeclarationFlag;
const
FoundDeclarationFlagNames: array[TFoundDeclarationFlag] of string = (
'fdfDoNotCache'
);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
type
TFindDeclarationParams = class; TFindDeclarationParams = class;
TFindContext = record TFindContext = record
@ -425,6 +431,7 @@ type
procedure ClearResult; procedure ClearResult;
procedure ClearInput; procedure ClearInput;
procedure ClearFoundProc; procedure ClearFoundProc;
procedure WriteDebugReport;
end; end;
@ -639,6 +646,8 @@ function FindContextAreEqual(const Context1, Context2: TFindContext): boolean;
function PredefinedIdentToExprTypeDesc(Identifier: PChar): TExpressionTypeDesc; function PredefinedIdentToExprTypeDesc(Identifier: PChar): TExpressionTypeDesc;
function FindDeclarationFlagsAsString( function FindDeclarationFlagsAsString(
const Flags: TFindDeclarationFlags): string; const Flags: TFindDeclarationFlags): string;
function FoundDeclarationFlagsAsString(
const Flags: TFoundDeclarationFlags): string;
implementation implementation
@ -658,6 +667,20 @@ begin
end; end;
end; end;
function FoundDeclarationFlagsAsString(
const Flags: TFoundDeclarationFlags): string;
var Flag: TFoundDeclarationFlag;
begin
Result:='';
for Flag:=Low(TFoundDeclarationFlag) to High(TFoundDeclarationFlag) do begin
if Flag in Flags then begin
if Result<>'' then
Result:=Result+', ';
Result:=Result+FoundDeclarationFlagNames[Flag];
end;
end;
end;
function PredefinedIdentToExprTypeDesc(Identifier: PChar): TExpressionTypeDesc; function PredefinedIdentToExprTypeDesc(Identifier: PChar): TExpressionTypeDesc;
begin begin
// predefined identifiers // predefined identifiers
@ -3049,7 +3072,7 @@ function TFindDeclarationTool.FindIdentifierInUsesSection(
var var
InAtom, UnitNameAtom: TAtomPosition; InAtom, UnitNameAtom: TAtomPosition;
NewCodeTool: TFindDeclarationTool; NewCodeTool: TFindDeclarationTool;
OldInput: TFindDeclarationInput; OldFlags: TFindDeclarationFlags;
begin begin
Result:=false; Result:=false;
MoveCursorToUsesEnd(UsesNode); MoveCursorToUsesEnd(UsesNode);
@ -3069,13 +3092,18 @@ begin
end; end;
end else begin end else begin
// open the unit // open the unit
{$IFDEF ShowTriedUnits}
writeln('TFindDeclarationTool.FindIdentifierInUsesSection Self=',MainFilename,
' UnitName=',GetAtom(UnitNameAtom));
Params.WriteDebugReport;
{$ENDIF}
NewCodeTool:=OpenCodeToolForUnit(UnitNameAtom,InAtom,false); NewCodeTool:=OpenCodeToolForUnit(UnitNameAtom,InAtom,false);
// search the identifier in the interface of the used unit // search the identifier in the interface of the used unit
Params.Save(OldInput); OldFlags:=Params.Flags;
Params.Flags:=[fdfIgnoreUsedUnits]+(fdfGlobalsSameIdent*Params.Flags) Params.Flags:=[fdfIgnoreUsedUnits]+(fdfGlobalsSameIdent*Params.Flags)
-[fdfExceptionOnNotFound]; -[fdfExceptionOnNotFound];
Result:=NewCodeTool.FindIdentifierInInterface(Self,Params); Result:=NewCodeTool.FindIdentifierInInterface(Self,Params);
Params.Load(OldInput); Params.Flags:=OldFlags;
if Result then exit; if Result then exit;
// restore the cursor // restore the cursor
MoveCursorToCleanPos(UnitNameAtom.StartPos); MoveCursorToCleanPos(UnitNameAtom.StartPos);
@ -3132,6 +3160,15 @@ var InterfaceNode: TCodeTreeNode;
SrcIsUsable: boolean; SrcIsUsable: boolean;
OldInput: TFindDeclarationInput; OldInput: TFindDeclarationInput;
CacheEntry: PInterfaceIdentCacheEntry; CacheEntry: PInterfaceIdentCacheEntry;
procedure RaiseWrongContext;
begin
writeln('TFindDeclarationTool.FindIdentifierInInterface.RaiseWrongContext');
Params.WriteDebugReport;
SaveRaiseException('TFindDeclarationTool.FindIdentifierInInterface '
+'Internal Error: Wrong CodeTool');
end;
begin begin
Result:=false; Result:=false;
// build code tree // build code tree
@ -3191,7 +3228,8 @@ begin
RaiseException(ctsInterfaceSectionNotFound); RaiseException(ctsInterfaceSectionNotFound);
Params.Save(OldInput); Params.Save(OldInput);
Params.Flags:=(fdfGlobalsSameIdent*Params.Flags) Params.Flags:=(fdfGlobalsSameIdent*Params.Flags)
-[fdfExceptionOnNotFound,fdfSearchInParentNodes]; -[fdfExceptionOnNotFound,fdfSearchInParentNodes]
+[fdfIgnoreUsedUnits];
Params.ContextNode:=InterfaceNode; Params.ContextNode:=InterfaceNode;
Result:=FindIdentifierInContext(Params); Result:=FindIdentifierInContext(Params);
Params.Load(OldInput); Params.Load(OldInput);
@ -3199,13 +3237,15 @@ begin
// save result in cache // save result in cache
if FInterfaceIdentifierCache=nil then if FInterfaceIdentifierCache=nil then
FInterfaceIdentifierCache:=TInterfaceIdentifierCache.Create(Self); FInterfaceIdentifierCache:=TInterfaceIdentifierCache.Create(Self);
if Result and (not (fdfCollect in Params.Flags)) then begin if Result then begin
// identifier exists in interface // identifier exists in interface
if (Params.NewNode.Desc<>ctnProcedure) then begin if Params.NewCodeTool<>Self then RaiseWrongContext;
if (not (fdfDoNotCache in Params.NewFlags))
and (not (fdfCollect in Params.Flags)) then begin
FInterfaceIdentifierCache.Add(OldInput.Identifier,Params.NewNode, FInterfaceIdentifierCache.Add(OldInput.Identifier,Params.NewNode,
Params.NewCleanPos); Params.NewCleanPos);
end else begin end else begin
// do not save proc identifiers // do not save proc identifiers or collect results
end; end;
end else end else
// identifier does not exist in interface // identifier does not exist in interface
@ -5858,6 +5898,49 @@ begin
FoundProc:=nil; FoundProc:=nil;
end; end;
procedure TFindDeclarationParams.WriteDebugReport;
begin
writeln('TFindDeclarationParams.WriteDebugReport Self=',HexStr(Cardinal(Self),8));
// input parameters:
writeln(' Flags=',FindDeclarationFlagsAsString(Flags));
writeln(' Identifier=',GetIdentifier(Identifier));
if ContextNode<>nil then
writeln(' ContextNode=',ContextNode.DescAsString)
else
writeln(' ContextNode=nil');
if OnIdentifierFound<>nil then
writeln(' OnIdentifierFound=',TFindDeclarationTool(TMethod(OnIdentifierFound).Data).MainFilename);
if IdentifierTool<>nil then
writeln(' IdentifierTool=',IdentifierTool.MainFilename)
else
writeln(' IdentifierTool=nil');
if FoundProc<>nil then begin
writeln(' FoundProc<>nil');
end;
// global params
if OnTopLvlIdentifierFound<>nil then
writeln(' OnTopLvlIdentifierFound=',TFindDeclarationTool(TMethod(OnTopLvlIdentifierFound).Code).MainFilename);
// results:
if NewNode<>nil then
writeln(' NewNode=',NewNode.DescAsString)
else
writeln(' NewNode=nil');
writeln(' NewCleanPos=',NewCleanPos);
if NewCodeTool<>nil then
writeln(' NewCodeTool=',NewCodeTool.MainFilename)
else
writeln(' NewCodeTool=nil');
if NewPos.Code<>nil then
writeln(' NewPos=',NewPos.Code.Filename,' x=',NewPos.X,' y=',NewPos.Y,' topline=',NewTopLine)
else
writeln(' NewPos=nil');
writeln(' NewFlags=',FoundDeclarationFlagsAsString(NewFlags));
writeln('');
end;
procedure TFindDeclarationParams.SetIdentifier( procedure TFindDeclarationParams.SetIdentifier(
NewIdentifierTool: TFindDeclarationTool; NewIdentifier: PChar; NewIdentifierTool: TFindDeclarationTool; NewIdentifier: PChar;
NewOnIdentifierFound: TOnIdentifierFound); NewOnIdentifierFound: TOnIdentifierFound);

View File

@ -846,7 +846,6 @@ function TPascalParserTool.KeyWordFuncClassVarTypeRecord: boolean;
var Level: integer; var Level: integer;
begin begin
Level:=1; Level:=1;
DoProgress;
while (CurPos.StartPos<=SrcLen) and (Level>0) do begin while (CurPos.StartPos<=SrcLen) and (Level>0) do begin
ReadNextAtom; ReadNextAtom;
if CurPos.Flag=cafRECORD then inc(Level) if CurPos.Flag=cafRECORD then inc(Level)
@ -1687,7 +1686,6 @@ end;
function TPascalParserTool.DoAtom: boolean; function TPascalParserTool.DoAtom: boolean;
begin begin
//writeln('[TPascalParserTool.DoAtom] A ',HexStr(Cardinal(CurKeyWordFuncList),8)); //writeln('[TPascalParserTool.DoAtom] A ',HexStr(Cardinal(CurKeyWordFuncList),8));
DoProgress;
if (CurPos.StartPos<=SrcLen) and (CurPos.EndPos>CurPos.StartPos) then begin if (CurPos.StartPos<=SrcLen) and (CurPos.EndPos>CurPos.StartPos) then begin
if IsIdentStartChar[Src[CurPos.StartPos]] then if IsIdentStartChar[Src[CurPos.StartPos]] then
Result:=CurKeyWordFuncList.DoItUpperCase(UpperSrc,CurPos.StartPos, Result:=CurKeyWordFuncList.DoItUpperCase(UpperSrc,CurPos.StartPos,
@ -1776,7 +1774,6 @@ begin
CurNode.Desc:=ctnFinalization; CurNode.Desc:=ctnFinalization;
CurSection:=CurNode.Desc; CurSection:=CurNode.Desc;
repeat repeat
DoProgress;
ReadNextAtom; ReadNextAtom;
if (CurSection=ctnInitialization) and UpAtomIs('FINALIZATION') then if (CurSection=ctnInitialization) and UpAtomIs('FINALIZATION') then
begin begin
@ -1974,7 +1971,6 @@ begin
RaiseUnknownBlockType; RaiseUnknownBlockType;
BlockStartPos:=CurPos.StartPos; BlockStartPos:=CurPos.StartPos;
repeat repeat
DoProgress;
ReadNextAtom; ReadNextAtom;
if (CurPos.StartPos>SrcLen) then if (CurPos.StartPos>SrcLen) then
SaveRaiseExceptionWithBlockStartHint(ctsUnexpectedEndOfSource); SaveRaiseExceptionWithBlockStartHint(ctsUnexpectedEndOfSource);
@ -2207,7 +2203,6 @@ begin
end else begin end else begin
// read till semicolon or 'end' // read till semicolon or 'end'
while (CurPos.Flag<>cafSemicolon) do begin while (CurPos.Flag<>cafSemicolon) do begin
DoProgress;
ReadNextAtom; ReadNextAtom;
if CurPos.Flag=cafEND then begin if CurPos.Flag=cafEND then begin
UndoReadNextAtom; UndoReadNextAtom;
@ -2415,7 +2410,6 @@ begin
CurNode.Desc:=ctnTypeSection; CurNode.Desc:=ctnTypeSection;
// read all type definitions Name = Type; // read all type definitions Name = Type;
repeat repeat
DoProgress;
ReadNextAtom; // name ReadNextAtom; // name
if AtomIsIdentifier(false) then begin if AtomIsIdentifier(false) then begin
CreateChildNode; CreateChildNode;
@ -2466,7 +2460,6 @@ begin
CurNode.Desc:=ctnVarSection; CurNode.Desc:=ctnVarSection;
// read all variable definitions Name : Type; [cvar;] [public [name '']] // read all variable definitions Name : Type; [cvar;] [public [name '']]
repeat repeat
DoProgress;
ReadNextAtom; // name ReadNextAtom; // name
if AtomIsIdentifier(false) then begin if AtomIsIdentifier(false) then begin
CreateChildNode; CreateChildNode;
@ -2516,7 +2509,6 @@ begin
CurNode.Desc:=ctnConstSection; CurNode.Desc:=ctnConstSection;
// read all constants Name = <Const>; or Name : type = <Const>; // read all constants Name = <Const>; or Name : type = <Const>;
repeat repeat
DoProgress;
ReadNextAtom; // name ReadNextAtom; // name
if AtomIsIdentifier(false) then begin if AtomIsIdentifier(false) then begin
CreateChildNode; CreateChildNode;
@ -2572,7 +2564,6 @@ begin
CurNode.Desc:=ctnResStrSection; CurNode.Desc:=ctnResStrSection;
// read all string constants Name = 'abc'; // read all string constants Name = 'abc';
repeat repeat
DoProgress;
ReadNextAtom; // name ReadNextAtom; // name
if AtomIsIdentifier(false) then begin if AtomIsIdentifier(false) then begin
CreateChildNode; CreateChildNode;
@ -2703,7 +2694,6 @@ begin
inc(Level); inc(Level);
ReadNextAtom; ReadNextAtom;
end; end;
DoProgress;
if (CurPos.StartPos>SrcLen) then if (CurPos.StartPos>SrcLen) then
SaveRaiseException(ctsEndForClassNotFound); SaveRaiseException(ctsEndForClassNotFound);
end; end;

View File

@ -40,11 +40,10 @@ uses
{$IFDEF IDE_MEM_CHECK} {$IFDEF IDE_MEM_CHECK}
MemCheck, MemCheck,
{$ENDIF} {$ENDIF}
Classes, LCLType, LCLLinux, Compiler, StdCtrls, Forms, Classes, LCLType, LCLLinux, StdCtrls, Buttons, Menus, ComCtrls, SysUtils,
Buttons, Menus, ComCtrls, Spin, SysUtils, FileCtrl, Controls, Graphics, ExtCtrls, Dialogs, FileCtrl, Forms, CodeToolManager,
Controls, Graphics, ExtCtrls, Dialogs, CodeToolManager, CodeCache, CodeCache, SynEditKeyCmds, LazConf, LazarusIDEStrConsts, ProjectDefs, Project,
SynEditKeyCmds, LazConf, LazarusIDEStrConsts, ProjectDefs, Project, BuildLazDialog, Compiler,
BuildLazDialog,
{$IFDEF EnablePkgs} {$IFDEF EnablePkgs}
ComponentReg, ComponentReg,
{$ELSE} {$ELSE}