mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-26 19:43:48 +02:00
MG: fixed find declaration node cache flags checking and updates for defines
git-svn-id: trunk@1480 -
This commit is contained in:
parent
969951d7fb
commit
84fc508f31
components/codetools
ide
@ -489,6 +489,10 @@ function TCodeToolManager.HandleException(AnException: Exception): boolean;
|
||||
var ErrorSrcTool: TCustomCodeTool;
|
||||
begin
|
||||
fErrorMsg:=AnException.Message;
|
||||
if not ((AnException is ELinkScannerError) or (AnException is ECodeToolError))
|
||||
then begin
|
||||
FErrorMsg:=AnException.ClassName+': '+FErrorMsg;
|
||||
end;
|
||||
if (AnException is ELinkScannerError) then begin
|
||||
fErrorCode:=TCodeBuffer(ELinkScannerError(AnException).Sender.Code);
|
||||
if fErrorCode<>nil then
|
||||
|
@ -101,7 +101,6 @@ const
|
||||
'UndefineAll', 'If', 'IfDef', 'IfNDef', 'ElseIf', 'Else', 'Directory'
|
||||
);
|
||||
|
||||
|
||||
type
|
||||
TDefineTemplateFlag = (dtfAutoGenerated, dtfProjectSpecific);
|
||||
TDefineTemplateFlags = set of TDefineTemplateFlag;
|
||||
@ -133,6 +132,7 @@ type
|
||||
property Prior: TDefineTemplate read FPrior;
|
||||
property FirstChild: TDefineTemplate read FFirstChild;
|
||||
property LastChild: TDefineTemplate read FLastChild;
|
||||
property Marked: boolean read FMarked write FMarked;
|
||||
|
||||
procedure AddChild(ADefineTemplate: TDefineTemplate);
|
||||
procedure InsertBehind(APrior: TDefineTemplate);
|
||||
@ -142,18 +142,26 @@ type
|
||||
function IsEqual(ADefineTemplate: TDefineTemplate;
|
||||
CheckSubNodes, CheckNextSiblings: boolean): boolean;
|
||||
function CreateCopy(OnlyMarked: boolean): TDefineTemplate;
|
||||
function FindRoot: TDefineTemplate;
|
||||
function FindChildByName(const AName: string): TDefineTemplate;
|
||||
function FindByName(const AName: string;
|
||||
WithSubChilds, WithNextSiblings: boolean): TDefineTemplate;
|
||||
function LoadFromXMLConfig(XMLConfig: TXMLConfig;
|
||||
const Path: string): boolean;
|
||||
function FindUniqueName(const Prefix: string): string;
|
||||
function LoadFromXMLConfig(XMLConfig: TXMLConfig; const Path: string): boolean;
|
||||
procedure LoadValuesFromXMLConfig(XMLConfig: TXMLConfig; const Path: string);
|
||||
procedure SaveToXMLConfig(XMLConfig: TXMLConfig; const Path: string;
|
||||
OnlyMarked, WithMergeInfo: boolean);
|
||||
class procedure MergeXMLConfig(ParentDefTempl: TDefineTemplate;
|
||||
var FirstSibling,LastSibling:TDefineTemplate;
|
||||
XMLConfig: TXMLConfig; const Path, NewNamePrefix: string);
|
||||
function SelfOrParentContainsFlag(AFlag: TDefineTemplateFlag): boolean;
|
||||
function IsAutoGenerated: boolean;
|
||||
function IsProjectSpecific: boolean;
|
||||
procedure MarkAllNonAutoNonProjSpecNodes;
|
||||
procedure MarkAllNonAutoProjSpecNodes;
|
||||
procedure MarkGlobals;
|
||||
procedure MarkProjectSpecificOnly;
|
||||
procedure MarkProjectSpecificAndParents;
|
||||
procedure MarkNonAutoCreated;
|
||||
procedure RemoveMarked;
|
||||
procedure Unbind;
|
||||
procedure Clear;
|
||||
constructor Create;
|
||||
@ -184,7 +192,12 @@ type
|
||||
dtspProjectSpecific, // save all (not auto) and project specific nodes
|
||||
dtspGlobals // save all (not auto) and (not proj spec) nodes
|
||||
);
|
||||
|
||||
TDefineTreeLoadPolicy = (
|
||||
dtlpAll, // replace all DefineTemplates
|
||||
dtlpProjectSpecific, // replace all (not auto) and project specific nodes
|
||||
dtlpGlobals // replace all (not auto) and (not proj spec) nodes
|
||||
);
|
||||
|
||||
TDefineTree = class
|
||||
private
|
||||
FFirstDefineTemplate: TDefineTemplate;
|
||||
@ -193,8 +206,9 @@ type
|
||||
FOnReadValue: TOnReadValue;
|
||||
FErrorTemplate: TDefineTemplate;
|
||||
FErrorDescription: string;
|
||||
function FindDirectoryInCache(const Path: string): TDirectoryDefines;
|
||||
function Calculate(DirDef: TDirectoryDefines): boolean;
|
||||
protected
|
||||
function FindDirectoryInCache(const Path: string): TDirectoryDefines;
|
||||
public
|
||||
function GetDefinesForDirectory(const Path: string): TExpressionEvaluator;
|
||||
function GetDefinesForVirtualDirectory: TExpressionEvaluator;
|
||||
@ -211,13 +225,19 @@ type
|
||||
property ErrorTemplate: TDefineTemplate read FErrorTemplate;
|
||||
property ErrorDescription: string read FErrorDescription;
|
||||
function LoadFromXMLConfig(XMLConfig: TXMLConfig;
|
||||
const Path: string; Policy: TDefineTreeSavePolicy): boolean;
|
||||
const Path: string; Policy: TDefineTreeLoadPolicy;
|
||||
const NewNamePrefix: string): boolean;
|
||||
function SaveToXMLConfig(XMLConfig: TXMLConfig;
|
||||
const Path: string; Policy: TDefineTreeSavePolicy): boolean;
|
||||
procedure ClearCache;
|
||||
procedure Clear;
|
||||
function IsEqual(SrcDefineTree: TDefineTree): boolean;
|
||||
procedure Assign(SrcDefineTree: TDefineTree);
|
||||
procedure RemoveMarked;
|
||||
procedure RemoveGlobals;
|
||||
procedure RemoveProjectSpecificOnly;
|
||||
procedure RemoveProjectSpecificAndParents;
|
||||
procedure RemoveNonAutoCreated;
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
function ConsistencyCheck: integer; // 0 = ok
|
||||
@ -257,6 +277,7 @@ const
|
||||
);
|
||||
|
||||
function DefineActionNameToAction(const s: string): TDefineAction;
|
||||
function DefineTemplateFlagsToString(Flags: TDefineTemplateFlags): string;
|
||||
|
||||
|
||||
implementation
|
||||
@ -279,6 +300,18 @@ begin
|
||||
Result:=da_None;
|
||||
end;
|
||||
|
||||
function DefineTemplateFlagsToString(Flags: TDefineTemplateFlags): string;
|
||||
var f: TDefineTemplateFlag;
|
||||
begin
|
||||
Result:='';
|
||||
for f:=Low(TDefineTemplateFlag) to High(TDefineTemplateFlag) do begin
|
||||
if f in Flags then begin
|
||||
if Result<>'' then Result:=Result+',';
|
||||
Result:=Result+DefineTemplateFlagNames[f];
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function CompareFilenames(const FileName1, Filename2: string): integer;
|
||||
begin
|
||||
{$ifdef CaseInsensitiveFilenames}
|
||||
@ -423,14 +456,14 @@ procedure TDefineTemplate.ComputeChildFlags;
|
||||
// accumulate flags of all childs in FChildFlags
|
||||
var ANode: TDefineTemplate;
|
||||
begin
|
||||
FChildFlags:=[];
|
||||
ANode:=Self;
|
||||
while ANode<>nil do begin
|
||||
if ANode.FirstChild<>nil then begin
|
||||
ANode.FChildFlags:=[];
|
||||
if ANode.FirstChild<>nil then
|
||||
ANode.FirstChild.ComputeChildFlags;
|
||||
FChildFlags:=FChildFlags+ANode.FirstChild.FChildFlags
|
||||
+ANode.FirstChild.Flags;
|
||||
end;
|
||||
if ANode.Parent<>nil then
|
||||
ANode.Parent.FChildFlags:=ANode.Parent.FChildFlags
|
||||
+ANode.Flags+ANode.FChildFlags;
|
||||
ANode:=ANode.Next;
|
||||
end;
|
||||
end;
|
||||
@ -439,19 +472,19 @@ procedure TDefineTemplate.ComputeParentFlags;
|
||||
// accumulate flags of all parents in FParentFlags
|
||||
var ANode: TDefineTemplate;
|
||||
begin
|
||||
if Parent<>nil then
|
||||
FParentFlags:=Parent.Flags+Parent.FParentFlags
|
||||
else
|
||||
FParentFlags:=[];
|
||||
ANode:=Self;
|
||||
while ANode<>nil do begin
|
||||
if ANode.Parent<>nil then
|
||||
ANode.FParentFlags:=ANode.Parent.Flags+ANode.Parent.FParentFlags
|
||||
else
|
||||
ANode.FParentFlags:=[];
|
||||
if ANode.FirstChild<>nil then
|
||||
ANode.FirstChild.ComputeParentFlags;
|
||||
ANode:=ANode.Next;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDefineTemplate.MarkAllNonAutoNonProjSpecNodes;
|
||||
procedure TDefineTemplate.MarkGlobals;
|
||||
// mark every node, that itself and its parents are not auto generated and
|
||||
// not project specific
|
||||
var ANode: TDefineTemplate;
|
||||
@ -462,14 +495,32 @@ begin
|
||||
ANode.FMarked:=((ANode.Flags+ANode.FParentFlags)
|
||||
*[dtfAutoGenerated,dtfProjectSpecific]=[]);
|
||||
if ANode.FirstChild<>nil then
|
||||
ANode.FirstChild.MarkAllNonAutoNonProjSpecNodes;
|
||||
ANode.FirstChild.MarkGlobals;
|
||||
ANode:=ANode.Next;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDefineTemplate.MarkAllNonAutoProjSpecNodes;
|
||||
procedure TDefineTemplate.MarkProjectSpecificOnly;
|
||||
// mark every node, that itself and its parents are not auto generated and
|
||||
// itself or one of its parents is project specific
|
||||
var ANode: TDefineTemplate;
|
||||
begin
|
||||
ComputeParentFlags;
|
||||
ComputeChildFlags;
|
||||
ANode:=Self;
|
||||
while ANode<>nil do begin
|
||||
ANode.FMarked:=((ANode.Flags+ANode.FParentFlags)*[dtfAutoGenerated]=[])
|
||||
and (dtfProjectSpecific in (ANode.Flags+ANode.FParentFlags));
|
||||
if ANode.FirstChild<>nil then
|
||||
ANode.FirstChild.MarkProjectSpecificOnly;
|
||||
ANode:=ANode.Next;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDefineTemplate.MarkProjectSpecificAndParents;
|
||||
// mark every node, that itself and its parents are not auto generated and
|
||||
// itself or one of its parents or one of its childs is project specific
|
||||
// Note: this can contain globals with project specific childs
|
||||
var ANode: TDefineTemplate;
|
||||
begin
|
||||
ComputeParentFlags;
|
||||
@ -480,11 +531,44 @@ begin
|
||||
and (dtfProjectSpecific
|
||||
in (ANode.Flags+ANode.FParentFlags+ANode.FChildFlags));
|
||||
if ANode.FirstChild<>nil then
|
||||
ANode.FirstChild.MarkAllNonAutoProjSpecNodes;
|
||||
ANode.FirstChild.MarkProjectSpecificAndParents;
|
||||
ANode:=ANode.Next;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDefineTemplate.MarkNonAutoCreated;
|
||||
// mark every node, that itself and its parent are not auto generated
|
||||
var ANode: TDefineTemplate;
|
||||
begin
|
||||
ComputeParentFlags;
|
||||
ANode:=Self;
|
||||
while ANode<>nil do begin
|
||||
ANode.FMarked:=not (dtfAutoGenerated in (ANode.Flags+ANode.FParentFlags));
|
||||
if ANode.FirstChild<>nil then
|
||||
ANode.FirstChild.MarkNonAutoCreated;
|
||||
ANode:=ANode.Next;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDefineTemplate.RemoveMarked;
|
||||
var ANode, NextNode: TDefineTemplate;
|
||||
begin
|
||||
ANode:=Self;
|
||||
while ANode<>nil do begin
|
||||
NextNode:=ANode.Next;
|
||||
if ANode.FMarked then begin
|
||||
writeln(' REMOVING ',ANode.Name);
|
||||
ANode.Unbind;
|
||||
ANode.Free;
|
||||
end else begin
|
||||
if ANode.FirstChild<>nil then begin
|
||||
ANode.FirstChild.RemoveMarked;
|
||||
end;
|
||||
end;
|
||||
ANode:=NextNode;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDefineTemplate.AddChild(ADefineTemplate: TDefineTemplate);
|
||||
// add as last child
|
||||
begin
|
||||
@ -573,7 +657,6 @@ procedure TDefineTemplate.Assign(ADefineTemplate: TDefineTemplate;
|
||||
WithSubNodes, WithNextSiblings: boolean);
|
||||
var ChildTemplate, CopyTemplate, NextTemplate: TDefineTemplate;
|
||||
begin
|
||||
if IsEqual(ADefineTemplate,WithSubNodes,WithNextSiblings) then exit;
|
||||
Clear;
|
||||
if ADefineTemplate=nil then exit;
|
||||
Name:=ADefineTemplate.Name;
|
||||
@ -670,6 +753,19 @@ begin
|
||||
//writeln('TDefineTemplate.CreateCopy B ',ConsistencyCheck);
|
||||
end;
|
||||
|
||||
function TDefineTemplate.FindRoot: TDefineTemplate;
|
||||
begin
|
||||
Result:=Self;
|
||||
repeat
|
||||
if Result.Parent<>nil then
|
||||
Result:=Result.Parent
|
||||
else if Result.Prior<>nil then
|
||||
Result:=Result.Prior
|
||||
else
|
||||
break;
|
||||
until false;
|
||||
end;
|
||||
|
||||
destructor TDefineTemplate.Destroy;
|
||||
begin
|
||||
Clear;
|
||||
@ -679,10 +775,10 @@ end;
|
||||
|
||||
function TDefineTemplate.LoadFromXMLConfig(XMLConfig: TXMLConfig;
|
||||
const Path: string): boolean;
|
||||
// obsolete
|
||||
var IndexedPath: string;
|
||||
i, LvlCount: integer;
|
||||
DefTempl, LastDefTempl: TDefineTemplate;
|
||||
f: TDefineTemplateFlag;
|
||||
begin
|
||||
Clear;
|
||||
LvlCount:=XMLConfig.GetValue(Path+'Count/Value',0);
|
||||
@ -701,20 +797,8 @@ begin
|
||||
inc(DefTempl.FParent.FChildCount);
|
||||
end;
|
||||
end;
|
||||
IndexedPath:=Path+IntToStr(i)+'/';
|
||||
DefTempl.Name:=XMLConfig.GetValue(IndexedPath+'Name/Value','no name');
|
||||
DefTempl.Description:=XMLConfig.GetValue(IndexedPath+'Description/Value','');
|
||||
DefTempl.Value:=XMLConfig.GetValue(IndexedPath+'Value/Value','');
|
||||
DefTempl.Variable:=XMLConfig.GetValue(IndexedPath+'Variable/Value','');
|
||||
DefTempl.Action:=DefineActionNameToAction(
|
||||
XMLConfig.GetValue(IndexedPath+'Action/Value',''));
|
||||
Flags:=[];
|
||||
for f:=Low(TDefineTemplateFlag) to High(TDefineTemplateFlag) do begin
|
||||
if XMLConfig.GetValue(IndexedPath+'Flags/'+DefineTemplateFlagNames[f]
|
||||
+'/Value',false)
|
||||
then
|
||||
Include(Flags,f);
|
||||
end;
|
||||
IndexedPath:=Path+'Node'+IntToStr(i)+'/';
|
||||
DefTempl.LoadValuesFromXMLConfig(XMLConfig,IndexedPath);
|
||||
// load childs
|
||||
if XMLConfig.GetValue(IndexedPath+'Count/Value',0)>0 then begin
|
||||
FFirstChild:=TDefineTemplate.Create;
|
||||
@ -726,6 +810,25 @@ begin
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
procedure TDefineTemplate.LoadValuesFromXMLConfig(XMLConfig: TXMLConfig;
|
||||
const Path: string);
|
||||
var f: TDefineTemplateFlag;
|
||||
begin
|
||||
Name:=XMLConfig.GetValue(Path+'Name/Value','no name');
|
||||
Description:=XMLConfig.GetValue(Path+'Description/Value','');
|
||||
Value:=XMLConfig.GetValue(Path+'Value/Value','');
|
||||
Variable:=XMLConfig.GetValue(Path+'Variable/Value','');
|
||||
Action:=DefineActionNameToAction(
|
||||
XMLConfig.GetValue(Path+'Action/Value',''));
|
||||
Flags:=[];
|
||||
for f:=Low(TDefineTemplateFlag) to High(TDefineTemplateFlag) do begin
|
||||
if (f<>dtfAutoGenerated)
|
||||
and (XMLConfig.GetValue(Path+'Flags/'+DefineTemplateFlagNames[f],false))
|
||||
then
|
||||
Include(Flags,f);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TDefineTemplate.SaveToXMLConfig(XMLConfig: TXMLConfig;
|
||||
const Path: string; OnlyMarked, WithMergeInfo: boolean);
|
||||
var IndexedPath, MergeNameInFront, MergeNameBehind: string;
|
||||
@ -745,7 +848,7 @@ begin
|
||||
if (DefTempl.FMarked) or (not OnlyMarked) then begin
|
||||
// save node
|
||||
inc(Index);
|
||||
IndexedPath:=Path+IntToStr(Index)+'/';
|
||||
IndexedPath:=Path+'Node'+IntToStr(Index)+'/';
|
||||
XMLConfig.SetValue(IndexedPath+'Name/Value',DefTempl.Name);
|
||||
XMLConfig.SetValue(IndexedPath+'Description/Value',DefTempl.Description);
|
||||
XMLConfig.SetValue(IndexedPath+'Value/Value',DefTempl.Value);
|
||||
@ -753,8 +856,9 @@ begin
|
||||
XMLConfig.SetValue(IndexedPath+'Action/Value',
|
||||
DefineActionNames[DefTempl.Action]);
|
||||
for f:=Low(TDefineTemplateFlag) to High(TDefineTemplateFlag) do begin
|
||||
XMLConfig.SetValue(IndexedPath+'Flags/'+DefineTemplateFlagNames[f]
|
||||
,f in Flags);
|
||||
if (f<>dtfAutoGenerated) then
|
||||
XMLConfig.SetValue(IndexedPath+'Flags/'+DefineTemplateFlagNames[f]
|
||||
,f in DefTempl.Flags);
|
||||
end;
|
||||
if WithMergeInfo then begin
|
||||
if DefTempl.Prior<>nil then
|
||||
@ -771,15 +875,120 @@ begin
|
||||
MergeNameBehind);
|
||||
end;
|
||||
// save childs
|
||||
if FFirstChild<>nil then
|
||||
FirstChild.SaveToXMLConfig(XMLConfig,IndexedPath,
|
||||
OnlyMarked,WithMergeInfo);
|
||||
if DefTempl.FFirstChild<>nil then
|
||||
DefTempl.FirstChild.SaveToXMLConfig(XMLConfig,IndexedPath,
|
||||
OnlyMarked,WithMergeInfo)
|
||||
else
|
||||
XMLConfig.SetValue(IndexedPath+'Count/Value',0);
|
||||
end;
|
||||
DefTempl:=DefTempl.Next;
|
||||
until DefTempl=nil;
|
||||
XMLConfig.SetValue(Path+'Count/Value',Index);
|
||||
end;
|
||||
|
||||
procedure TDefineTemplate.MergeXMLConfig(ParentDefTempl: TDefineTemplate;
|
||||
var FirstSibling, LastSibling: TDefineTemplate;
|
||||
XMLConfig: TXMLConfig; const Path, NewNamePrefix: string);
|
||||
var i, NewCount: integer;
|
||||
NewNode, PosNode: TDefineTemplate;
|
||||
MergeNameInFront, MergeNameBehind, IndexedPath: string;
|
||||
Inserted: boolean;
|
||||
begin
|
||||
NewCount:=XMLConfig.GetValue(Path+'Count/Value',0);
|
||||
if NewCount=0 then exit;
|
||||
for i:=1 to NewCount do begin
|
||||
// load each node and merge it
|
||||
IndexedPath:=Path+'Node'+IntToStr(i)+'/';
|
||||
NewNode:=TDefineTemplate.Create;
|
||||
NewNode.LoadValuesFromXMLConfig(XMLConfig,IndexedPath);
|
||||
Inserted:=false;
|
||||
if NewNode.Name<>'' then begin
|
||||
// node has a name -> test if already exists
|
||||
PosNode:=FirstSibling;
|
||||
while (PosNode<>nil)
|
||||
and (AnsiCompareText(PosNode.Name,NewNode.Name)<>0) do
|
||||
PosNode:=PosNode.Next;
|
||||
if PosNode<>nil then begin
|
||||
// node with same name already exists -> check if it is a copy
|
||||
if NewNode.IsEqual(PosNode,false,false) then begin
|
||||
// node already exists
|
||||
NewNode.Free;
|
||||
NewNode:=PosNode;
|
||||
end else begin
|
||||
// node has same name, but different values
|
||||
// -> rename node
|
||||
NewNode.Name:=NewNode.FindUniqueName(NewNamePrefix);
|
||||
if (not PosNode.IsProjectSpecific) or (NewNode.IsProjectSpecific) then
|
||||
begin
|
||||
// insert behind PosNode
|
||||
NewNode.InsertBehind(PosNode);
|
||||
end else begin
|
||||
// insert global NewNode in front of project specific PosNode
|
||||
NewNode.InsertInFront(PosNode);
|
||||
end;
|
||||
end;
|
||||
Inserted:=true;
|
||||
end;
|
||||
end;
|
||||
if not Inserted then begin
|
||||
// node name is unique or empty -> insert node
|
||||
MergeNameInFront:=XMLConfig.GetValue(
|
||||
IndexedPath+'MergeNameInFront/Value','');
|
||||
if MergeNameInFront<>'' then begin
|
||||
// last time, node was inserted behind MergeNameInFront
|
||||
// -> search MergeNameInFront
|
||||
PosNode:=LastSibling;
|
||||
while (PosNode<>nil)
|
||||
and (AnsiCompareText(PosNode.Name,MergeNameInFront)<>0) do
|
||||
PosNode:=PosNode.Prior;
|
||||
if PosNode<>nil then begin
|
||||
// MergeNameInFront found -> insert behind
|
||||
NewNode.InsertBehind(PosNode);
|
||||
Inserted:=true;
|
||||
end;
|
||||
end;
|
||||
if not Inserted then begin
|
||||
MergeNameBehind:=XMLConfig.GetValue(
|
||||
IndexedPath+'MergeNameBehind/Value','');
|
||||
if MergeNameBehind<>'' then begin
|
||||
// last time, node was inserted in front of MergeNameBehind
|
||||
// -> search MergeNameBehind
|
||||
PosNode:=FirstSibling;
|
||||
while (PosNode<>nil)
|
||||
and (AnsiCompareText(PosNode.Name,MergeNameBehind)<>0) do
|
||||
PosNode:=PosNode.Next;
|
||||
if PosNode<>nil then begin
|
||||
// MergeNameBehind found -> insert in front
|
||||
NewNode.InsertInFront(PosNode);
|
||||
Inserted:=true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
if not Inserted then begin
|
||||
// no merge position found -> add as last
|
||||
if LastSibling<>nil then begin
|
||||
NewNode.InsertBehind(LastSibling);
|
||||
end else if ParentDefTempl<>nil then begin
|
||||
ParentDefTempl.AddChild(NewNode);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
// NewNode is now inserted -> update FirstSibling and LastSibling
|
||||
if FirstSibling=nil then begin
|
||||
FirstSibling:=NewNode;
|
||||
LastSibling:=NewNode;
|
||||
end else begin
|
||||
while FirstSibling.Prior<>nil do
|
||||
FirstSibling:=FirstSibling.Prior;
|
||||
while LastSibling.Next<>nil do
|
||||
LastSibling:=LastSibling.Next;
|
||||
end;
|
||||
// insert childs
|
||||
MergeXMLConfig(NewNode,NewNode.FFirstChild,NewNode.FLastChild,
|
||||
XMLConfig,IndexedPath,NewNamePrefix);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDefineTemplate.ConsistencyCheck: integer;
|
||||
var RealChildCount: integer;
|
||||
DefTempl: TDefineTemplate;
|
||||
@ -832,15 +1041,20 @@ procedure TDefineTemplate.WriteDebugReport;
|
||||
if ANode=nil then exit;
|
||||
ActionStr:=DefineActionNames[ANode.Action];
|
||||
writeln(Prefix,'Self=',HexStr(Cardinal(ANode),8),
|
||||
' Name="',ANode.Name,'"',
|
||||
' Consistency=',ANode.ConsistencyCheck,
|
||||
' Next=',HexStr(Cardinal(ANode.Next),8),
|
||||
' Prior=',HexStr(Cardinal(ANode.Prior),8),
|
||||
' Action=',ActionStr,
|
||||
' Name="',ANode.Name,'"');
|
||||
' Flags=[',DefineTemplateFlagsToString(ANode.Flags),']',
|
||||
' FParentFlags=[',DefineTemplateFlagsToString(ANode.FParentFlags),']',
|
||||
' FChildFlags=[',DefineTemplateFlagsToString(ANode.FChildFlags),']',
|
||||
' Marked=',ANode.Marked
|
||||
);
|
||||
writeln(Prefix+' + Description="',ANode.Description,'"');
|
||||
writeln(Prefix+' + Variable="',ANode.Variable,'"');
|
||||
writeln(Prefix+' + Value="',ANode.Value,'"');
|
||||
WriteNode(ANode.FFirstChild,Prefix+' ');
|
||||
WriteNode(ANode.FirstChild,Prefix+' ');
|
||||
WriteNode(ANode.Next,Prefix);
|
||||
end;
|
||||
|
||||
@ -858,9 +1072,12 @@ begin
|
||||
and (Variable=ADefineTemplate.Variable)
|
||||
and (Value=ADefineTemplate.Value)
|
||||
and (Action=ADefineTemplate.Action)
|
||||
and (Flags=ADefineTemplate.Flags)
|
||||
and (ChildCount=ADefineTemplate.ChildCount);
|
||||
and (Flags=ADefineTemplate.Flags);
|
||||
if Result and CheckSubNodes then begin
|
||||
if (ChildCount<>ADefineTemplate.ChildCount) then begin
|
||||
Result:=false;
|
||||
exit;
|
||||
end;
|
||||
SrcNode:=FirstChild;
|
||||
DestNode:=ADefineTemplate.FirstChild;
|
||||
if SrcNode<>nil then
|
||||
@ -869,8 +1086,13 @@ begin
|
||||
if Result and CheckNextSiblings then begin
|
||||
SrcNode:=Next;
|
||||
DestNode:=ADefineTemplate.Next;
|
||||
if SrcNode<>nil then
|
||||
Result:=SrcNode.IsEqual(DestNode,CheckSubNodes,CheckNextSiblings);
|
||||
while (SrcNode<>nil) and (DestNode<>nil) do begin
|
||||
Result:=SrcNode.IsEqual(DestNode,CheckSubNodes,false);
|
||||
if not Result then exit;
|
||||
SrcNode:=SrcNode.Next;
|
||||
DestNode:=DestNode.Next;
|
||||
end;
|
||||
Result:=(SrcNode=nil) and (DestNode=nil);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -940,6 +1162,18 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TDefineTemplate.FindUniqueName(const Prefix: string): string;
|
||||
var Root: TDefineTemplate;
|
||||
i: integer;
|
||||
begin
|
||||
Root:=FindRoot;
|
||||
i:=0;
|
||||
repeat
|
||||
inc(i);
|
||||
Result:=Prefix+IntToStr(i);
|
||||
until Root.FindByName(Result,true,true)=nil;
|
||||
end;
|
||||
|
||||
|
||||
{ TDirectoryDefines }
|
||||
|
||||
@ -969,12 +1203,14 @@ end;
|
||||
function TDefineTree.IsEqual(SrcDefineTree: TDefineTree): boolean;
|
||||
begin
|
||||
Result:=false;
|
||||
if SrcDefineTree=nil then exit;
|
||||
if (FFirstDefineTemplate=nil) xor (SrcDefineTree.FFirstDefineTemplate=nil)
|
||||
then exit;
|
||||
if (FFirstDefineTemplate<>nil)
|
||||
and (not FFirstDefineTemplate.IsEqual(
|
||||
SrcDefineTree.FFirstDefineTemplate,true,true))
|
||||
then exit;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
procedure TDefineTree.Assign(SrcDefineTree: TDefineTree);
|
||||
@ -1029,6 +1265,45 @@ begin
|
||||
Result:=nil;
|
||||
end;
|
||||
|
||||
procedure TDefineTree.RemoveMarked;
|
||||
var NewFirstNode: TDefineTemplate;
|
||||
begin
|
||||
if FFirstDefineTemplate=nil then exit;
|
||||
NewFirstNode:=FFirstDefineTemplate;
|
||||
while (NewFirstNode<>nil) and NewFirstNode.Marked do
|
||||
NewFirstNode:=NewFirstNode.Next;
|
||||
FFirstDefineTemplate.RemoveMarked;
|
||||
FFirstDefineTemplate:=NewFirstNode;
|
||||
end;
|
||||
|
||||
procedure TDefineTree.RemoveGlobals;
|
||||
begin
|
||||
if FFirstDefineTemplate=nil then exit;
|
||||
FFirstDefineTemplate.MarkGlobals;
|
||||
RemoveMarked;
|
||||
end;
|
||||
|
||||
procedure TDefineTree.RemoveProjectSpecificOnly;
|
||||
begin
|
||||
if FFirstDefineTemplate=nil then exit;
|
||||
FFirstDefineTemplate.MarkProjectSpecificOnly;
|
||||
RemoveMarked;
|
||||
end;
|
||||
|
||||
procedure TDefineTree.RemoveProjectSpecificAndParents;
|
||||
begin
|
||||
if FFirstDefineTemplate=nil then exit;
|
||||
FFirstDefineTemplate.MarkProjectSpecificAndParents;
|
||||
RemoveMarked;
|
||||
end;
|
||||
|
||||
procedure TDefineTree.RemoveNonAutoCreated;
|
||||
begin
|
||||
if FFirstDefineTemplate=nil then exit;
|
||||
FFirstDefineTemplate.MarkNonAutoCreated;
|
||||
RemoveMarked;
|
||||
end;
|
||||
|
||||
function TDefineTree.GetDefinesForDirectory(
|
||||
const Path: string): TExpressionEvaluator;
|
||||
var ExpPath: string;
|
||||
@ -1291,34 +1566,39 @@ begin
|
||||
end;
|
||||
|
||||
function TDefineTree.LoadFromXMLConfig(XMLConfig: TXMLConfig;
|
||||
const Path: string; Policy: TDefineTreeSavePolicy): boolean;
|
||||
const Path: string; Policy: TDefineTreeLoadPolicy;
|
||||
const NewNamePrefix: string): boolean;
|
||||
var LastDefTempl: TDefineTemplate;
|
||||
begin
|
||||
case Policy of
|
||||
|
||||
dtspGlobals:
|
||||
dtlpGlobals:
|
||||
begin
|
||||
// replace globals
|
||||
|
||||
RemoveGlobals;
|
||||
end;
|
||||
|
||||
dtspProjectSpecific:
|
||||
dtlpProjectSpecific:
|
||||
begin
|
||||
// replace project specific
|
||||
|
||||
RemoveProjectSpecificOnly;
|
||||
end;
|
||||
|
||||
else
|
||||
begin
|
||||
// replace all
|
||||
FreeAndNil(FFirstDefineTemplate);
|
||||
if XMLConfig.GetValue(Path+'/Count/Value',0)>0 then begin
|
||||
FFirstDefineTemplate:=TDefineTemplate.Create;
|
||||
Result:=FFirstDefineTemplate.LoadFromXMLConfig(XMLConfig,Path);
|
||||
end else begin
|
||||
Result:=true;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
// import new defines
|
||||
LastDefTempl:=FFirstDefineTemplate;
|
||||
if LastDefTempl<>nil then begin
|
||||
while LastDefTempl.Next<>nil do
|
||||
LastDefTempl:=LastDefTempl.Next;
|
||||
end;
|
||||
TDefineTemplate.MergeXMLConfig(nil,FFirstDefineTemplate,LastDefTempl,
|
||||
XMLConfig,Path,NewNamePrefix);
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TDefineTree.SaveToXMLConfig(XMLConfig: TXMLConfig;
|
||||
@ -1331,13 +1611,13 @@ begin
|
||||
case Policy of
|
||||
dtspProjectSpecific:
|
||||
begin
|
||||
FFirstDefineTemplate.MarkAllNonAutoProjSpecNodes;
|
||||
FFirstDefineTemplate.MarkProjectSpecificAndParents;
|
||||
FFirstDefineTemplate.SaveToXMLConfig(XMLConfig,Path,true,true);
|
||||
end;
|
||||
|
||||
dtspGlobals:
|
||||
begin
|
||||
FFirstDefineTemplate.MarkAllNonAutoNonProjSpecNodes;
|
||||
FFirstDefineTemplate.MarkGlobals;
|
||||
FFirstDefineTemplate.SaveToXMLConfig(XMLConfig,Path,true,true);
|
||||
end;
|
||||
else
|
||||
|
@ -46,7 +46,7 @@ interface
|
||||
{ $DEFINE ShowTriedIdentifiers}
|
||||
{ $DEFINE ShowExprEval}
|
||||
{ $DEFINE ShowFoundIdentifier}
|
||||
{ $DEFINE ShowCachedIdentifiers}
|
||||
{ $DEFINE ShowInterfaceCache}
|
||||
{ $DEFINE ShowNodeCache}
|
||||
{ $DEFINE ShowBaseTypeCache}
|
||||
|
||||
@ -269,6 +269,8 @@ type
|
||||
Params: TFindDeclarationParams): boolean;
|
||||
function FindIdentifierInUsedUnit(const AnUnitName: string;
|
||||
Params: TFindDeclarationParams): boolean;
|
||||
protected
|
||||
function NodeIsInAMethod(Node: TCodeTreeNode): boolean;
|
||||
protected
|
||||
procedure DoDeleteNodes; override;
|
||||
procedure ClearNodeCaches(Force: boolean);
|
||||
@ -923,6 +925,7 @@ var
|
||||
LastNodeCache: TCodeTreeNodeCache;
|
||||
LastCacheEntry: PCodeTreeNodeCacheEntry;
|
||||
SearchRangeFlags: TNodeCacheEntryFlags;
|
||||
NodeCacheEntryFlags: TNodeCacheEntryFlags;
|
||||
|
||||
function FindInNodeCache: boolean;
|
||||
var
|
||||
@ -934,7 +937,7 @@ var
|
||||
// NodeCache changed -> search nearest cache entry for the identifier
|
||||
LastNodeCache:=NodeCache;
|
||||
if NodeCache<>nil then begin
|
||||
LastCacheEntry:=NodeCache.FindNearest(Params.identifier,
|
||||
LastCacheEntry:=NodeCache.FindNearest(Params.Identifier,
|
||||
ContextNode.StartPos,ContextNode.EndPos,
|
||||
not (fdfSearchForward in Params.Flags));
|
||||
end else
|
||||
@ -943,22 +946,36 @@ var
|
||||
if (LastCacheEntry<>nil)
|
||||
and (LastCacheEntry^.CleanStartPos<ContextNode.EndPos)
|
||||
and (LastCacheEntry^.CleanEndPos>ContextNode.StartPos)
|
||||
and ((NodeCacheEntryFlags-LastCacheEntry^.Flags)=[])
|
||||
then begin
|
||||
// cached result found
|
||||
Params.SetResult(LastCacheEntry);
|
||||
{$IFDEF ShowNodeCache}
|
||||
writeln(':::: TFindDeclarationTool.FindIdentifierInContext.FindInNodeCache');
|
||||
writeln(' Ident=',GetIdentifier(Params.Identifier),
|
||||
writeln(' Ident=',GetIdentifier(Params.Identifier),
|
||||
' ContextNode=',ContextNode.DescAsString,
|
||||
' Self=',MainFilename);
|
||||
if (Params.NewNode<>nil) then
|
||||
writeln(' NewTool=',Params.NewCodeTool.MainFilename,
|
||||
' NewNode=',Params.NewNode.DescAsString);
|
||||
writeln(' NewTool=',Params.NewCodeTool.MainFilename,
|
||||
' NewNode=',Params.NewNode.DescAsString)
|
||||
else
|
||||
writeln(' cache says: identifier NOT FOUND');
|
||||
{$ENDIF}
|
||||
Result:=true;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SetResultBeforeExit(NewResult: boolean);
|
||||
begin
|
||||
FindIdentifierInContext:=NewResult;
|
||||
if not NewResult and (fdfExceptionOnNotFound in Params.Flags) then begin
|
||||
if Params.IdentifierTool.IsPCharInSrc(Params.Identifier) then
|
||||
Params.IdentifierTool.MoveCursorToCleanPos(Params.Identifier);
|
||||
Params.IdentifierTool.RaiseException('Identifier not found '
|
||||
+'"'+GetIdentifier(Params.Identifier)+'"');
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=false;
|
||||
ContextNode:=Params.ContextNode;
|
||||
@ -977,22 +994,32 @@ begin
|
||||
try
|
||||
LastNodeCache:=nil;
|
||||
LastCacheEntry:=nil;
|
||||
repeat
|
||||
NodeCacheEntryFlags:=[];
|
||||
if fdfSearchInParentNodes in Params.Flags then
|
||||
Include(NodeCacheEntryFlags,ncefSearchedInParents);
|
||||
if fdfSearchInAncestors in Params.Flags then
|
||||
Include(NodeCacheEntryFlags,ncefSearchedInAncestors);
|
||||
{$IFDEF ShowTriedContexts}
|
||||
writeln('[TFindDeclarationTool.FindIdentifierInContext] A Ident=',
|
||||
'"',GetIdentifier(Params.Identifier),'"',
|
||||
' Context="',ContextNode.DescAsString,'" "',copy(Src,ContextNode.StartPos,20),'"',
|
||||
' Flags=[',FindDeclarationFlagsAsString(Params.Flags),']'
|
||||
);
|
||||
if (ContextNode.Desc=ctnClass) then
|
||||
writeln(' ContextNode.LastChild=',ContextNode.LastChild<>nil);
|
||||
{$ENDIF}
|
||||
repeat
|
||||
{$IFDEF ShowTriedIdentifiers}
|
||||
writeln('[TFindDeclarationTool.FindIdentifierInContext] A Ident=',
|
||||
'"',GetIdentifier(Params.Identifier),'"',
|
||||
' Context="',ContextNode.DescAsString,'" "',copy(Src,ContextNode.StartPos,20),'"',
|
||||
' Flags=[',FindDeclarationFlagsAsString(Params.Flags),']'
|
||||
);
|
||||
{$ENDIF}
|
||||
// search identifier in current context
|
||||
LastContextNode:=ContextNode;
|
||||
if not (fdfIgnoreCurContextNode in Params.Flags) then begin
|
||||
// search in cache
|
||||
if FindInNodeCache then begin
|
||||
Result:=(Params.NewNode<>nil);
|
||||
SetResultBeforeExit(Params.NewNode<>nil);
|
||||
exit;
|
||||
end;
|
||||
if FirstSearchedNode=nil then FirstSearchedNode:=ContextNode;
|
||||
@ -1065,7 +1092,7 @@ writeln(' Definition Identifier found="',GetIdentifier(Params.Identifier),'"');
|
||||
end else begin
|
||||
IdentifierFoundResult:=DoOnIdentifierFound(Params,ContextNode);
|
||||
if IdentifierFoundResult in [ifrAbortSearch,ifrSuccess] then begin
|
||||
Result:=(IdentifierFoundResult=ifrSuccess);
|
||||
SetResultBeforeExit(IdentifierFoundResult=ifrSuccess);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
@ -1080,7 +1107,7 @@ writeln(' Definition Identifier found="',GetIdentifier(Params.Identifier),'"');
|
||||
IdentifierFoundResult:=
|
||||
FindIdentifierInProcContext(ContextNode,Params);
|
||||
if IdentifierFoundResult in [ifrAbortSearch,ifrSuccess] then begin
|
||||
Result:=(IdentifierFoundResult=ifrSuccess);
|
||||
SetResultBeforeExit(IdentifierFoundResult=ifrSuccess);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
@ -1111,7 +1138,7 @@ writeln(' Source Name Identifier found="',GetIdentifier(Params.Identifier),'"')
|
||||
end else begin
|
||||
IdentifierFoundResult:=DoOnIdentifierFound(Params,ContextNode);
|
||||
if IdentifierFoundResult in [ifrAbortSearch,ifrSuccess] then begin
|
||||
Result:=(IdentifierFoundResult=ifrSuccess);
|
||||
SetResultBeforeExit(IdentifierFoundResult=ifrSuccess);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
@ -1148,7 +1175,7 @@ writeln(' Property Identifier found="',GetIdentifier(Params.Identifier),'"');
|
||||
end else begin
|
||||
IdentifierFoundResult:=DoOnIdentifierFound(Params,ContextNode);
|
||||
if IdentifierFoundResult in [ifrAbortSearch,ifrSuccess] then begin
|
||||
Result:=(IdentifierFoundResult=ifrSuccess);
|
||||
SetResultBeforeExit(IdentifierFoundResult=ifrSuccess);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
@ -1170,7 +1197,7 @@ writeln(' Property Identifier found="',GetIdentifier(Params.Identifier),'"');
|
||||
begin
|
||||
// pointer types can be forward definitions
|
||||
Params.ContextNode:=ContextNode.Parent;
|
||||
Result:=FindForwardIdentifier(Params,IsForward);
|
||||
SetResultBeforeExit(FindForwardIdentifier(Params,IsForward));
|
||||
exit;
|
||||
end;
|
||||
|
||||
@ -1195,14 +1222,15 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] IgnoreCurContext');
|
||||
{$IFDEF ShowTriedContexts}
|
||||
writeln('[TFindDeclarationTool.FindIdentifierInContext] no prior node accessible ContextNode=',ContextNode.DescAsString);
|
||||
{$ENDIF}
|
||||
exit;
|
||||
ContextNode:=nil;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
repeat
|
||||
// search for prior node
|
||||
{$IFDEF ShowTriedContexts}
|
||||
{$IFDEF ShowTriedIdentifiers}
|
||||
//writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching prior node of ',ContextNode.DescAsString);
|
||||
{$ENDIF}
|
||||
LastSearchedNode:=ContextNode;
|
||||
@ -1230,7 +1258,7 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] no prior node accessible
|
||||
ContextNode:=ContextNode.PriorBrother
|
||||
else
|
||||
ContextNode:=ContextNode.NextBrother;
|
||||
{$IFDEF ShowTriedContexts}
|
||||
{$IFDEF ShowTriedIdentifiers}
|
||||
writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching in PriorBrother ContextNode=',ContextNode.DescAsString);
|
||||
{$ENDIF}
|
||||
// it is not always allowed to search in every node on the same lvl:
|
||||
@ -1250,7 +1278,7 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching in PriorBrothe
|
||||
begin
|
||||
// search next in parent
|
||||
ContextNode:=ContextNode.Parent;
|
||||
{$IFDEF ShowTriedContexts}
|
||||
{$IFDEF ShowTriedIdentifiers}
|
||||
writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching in Parent ContextNode=',ContextNode.DescAsString);
|
||||
{$ENDIF}
|
||||
case ContextNode.Desc of
|
||||
@ -1290,7 +1318,7 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching in Parent Con
|
||||
finally
|
||||
if Result and (not (fdfDoNotCache in Params.NewFlags))
|
||||
and (FirstSearchedNode<>nil) then begin
|
||||
// add result to caches
|
||||
// cache result
|
||||
AddResultToNodeCaches(Params.Identifier,FirstSearchedNode,ContextNode,
|
||||
fdfSearchForward in Params.Flags,Params,SearchRangeFlags);
|
||||
end;
|
||||
@ -1302,12 +1330,7 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching in Parent Con
|
||||
fdfSearchForward in Params.Flags,nil,SearchRangeFlags);
|
||||
end;
|
||||
|
||||
if fdfExceptionOnNotFound in Params.Flags then begin
|
||||
if Params.IdentifierTool.IsPCharInSrc(Params.Identifier) then
|
||||
Params.IdentifierTool.MoveCursorToCleanPos(Params.Identifier);
|
||||
Params.IdentifierTool.RaiseException('Identifier not found '
|
||||
+'"'+GetIdentifier(Params.Identifier)+'"');
|
||||
end;
|
||||
SetResultBeforeExit(false);
|
||||
end;
|
||||
|
||||
function TFindDeclarationTool.FindEnumInContext(
|
||||
@ -1535,6 +1558,22 @@ writeln('');
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{ ToDo: check, if this is needed for Delphi:
|
||||
|
||||
if (NextAtomType in [atSpace])
|
||||
and CompareSrcIdentifier(CurAtom.StartPos,'FREE')
|
||||
and ((Result.Node.Desc=ctnClass) or NodeIsInAMethod(Result.Node)) then
|
||||
begin
|
||||
// FREE calls the destructor of an object
|
||||
Params.Save(OldInput);
|
||||
Params.SetIdentifier(Self,'DESTRUCTOR',nil);
|
||||
Exclude(Params.Flags,fdfExceptionOnNotFound);
|
||||
if Result.Tool.FindIdentifierInContext(Params) then begin
|
||||
Result:=CreateFindContext(Params);
|
||||
exit;
|
||||
end;
|
||||
Params.Load(OldInput);
|
||||
end;}
|
||||
// find sub identifier
|
||||
Params.Save(OldInput);
|
||||
try
|
||||
@ -2016,10 +2055,9 @@ var
|
||||
NameAtom: TAtomPosition;
|
||||
begin
|
||||
Result:=ifrProceedSearch;
|
||||
// if proc is a method, search in class
|
||||
// if proc is a method body, search in class
|
||||
// -> find class name
|
||||
MoveCursorToNodeStart(ProcContextNode);
|
||||
ReadNextAtom; // read keyword
|
||||
MoveCursorToNodeStart(ProcContextNode.FirstChild);
|
||||
ReadNextAtom; // read name
|
||||
NameAtom:=CurPos;
|
||||
ReadNextAtom;
|
||||
@ -2722,7 +2760,7 @@ writeln(DebugPrefix,'TFindDeclarationTool.FindIdentifierInInterface',
|
||||
CacheEntry:=FInterfaceIdentifierCache.FindIdentifier(Params.Identifier);
|
||||
if CacheEntry<>nil then begin
|
||||
// identifier in cache found
|
||||
{$IFDEF ShowCachedIdentifiers}
|
||||
{$IFDEF ShowInterfaceCache}
|
||||
writeln('[TFindDeclarationTool.FindIdentifierInInterface] Ident already in cache:',
|
||||
' Exists=',CacheEntry^.Node<>nil);
|
||||
{$ENDIF}
|
||||
@ -2864,6 +2902,25 @@ writeln('[TFindDeclarationTool.FindIdentifierInUsedUnit] ',
|
||||
end;
|
||||
end;
|
||||
|
||||
function TFindDeclarationTool.NodeIsInAMethod(Node: TCodeTreeNode): boolean;
|
||||
begin
|
||||
Result:=false;
|
||||
while (Node<>nil) do begin
|
||||
if (Node.Desc=ctnProcedure) then begin
|
||||
|
||||
// ToDo: ppu, ppw, dcu
|
||||
|
||||
MoveCursorToNodeStart(Node.FirstChild); // ctnProcedureHead
|
||||
ReadNextAtom;
|
||||
if not AtomIsIdentifier(false) then continue;
|
||||
ReadNextAtom;
|
||||
if not AtomIsChar('.') then continue;
|
||||
Result:=true;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TFindDeclarationTool.FindIdentifierInHiddenUsedUnits(
|
||||
Params: TFindDeclarationParams): boolean;
|
||||
const
|
||||
@ -3882,22 +3939,28 @@ var Node: TCodeTreeNode;
|
||||
NewCleanPos: integer;
|
||||
begin
|
||||
{$IFDEF ShowNodeCache}
|
||||
//if CompareSrcIdentifiers(Identifier,'TDefineTree') then writeln('=================================');
|
||||
write('TFindDeclarationTool.AddResultToNodeCaches ',
|
||||
' Ident=',GetIdentifier(Identifier),
|
||||
' StartNode=',StartNode.DescAsString,'="',copy(Src,StartNode.StartPos-10,10),'|',copy(Src,StartNode.StartPos,15),'"');
|
||||
' Ident=',GetIdentifier(Identifier));
|
||||
write(' SearchedForward=',SearchedForward);
|
||||
write(' Flags=[');
|
||||
if ncefSearchedInParents in SearchRangeFlags then write('Parents');
|
||||
if ncefSearchedInAncestors in SearchRangeFlags then write(',Ancestors');
|
||||
writeln(']');
|
||||
write(' StartNode=',StartNode.DescAsString,'="',copy(Src,StartNode.StartPos-10,10),'|',copy(Src,StartNode.StartPos,15),'"');
|
||||
if EndNode<>nil then
|
||||
write(' EndNode=',EndNode.DescAsString,'="',copy(Src,EndNode.StartPos,25),'"')
|
||||
else
|
||||
write(' EndNode=nil');
|
||||
write(' SearchedForward=',SearchedForward);
|
||||
writeln('');
|
||||
writeln(' Self=',MainFilename);
|
||||
writeln(' Self=',MainFilename);
|
||||
if Params<>nil then begin
|
||||
writeln(' NewNode=',Params.NewNode.DescAsString,
|
||||
writeln(' NewNode=',Params.NewNode.DescAsString,
|
||||
' NewTool=',Params.NewCodeTool.MainFilename);
|
||||
end else begin
|
||||
writeln(' NOT FOUND');
|
||||
writeln(' NOT FOUND');
|
||||
end;
|
||||
//if CompareSrcIdentifiers(Identifier,'TDefineTree') then writeln('=================================');
|
||||
{$ENDIF}
|
||||
Node:=StartNode;
|
||||
LastNodeCache:=nil;
|
||||
|
@ -35,7 +35,7 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, LCLLinux, Forms, Controls, Buttons, StdCtrls, ComCtrls,
|
||||
ExtCtrls, Menus, LResources, Graphics, Dialogs, ImgList, SynEdit,
|
||||
ExtCtrls, Menus, LResources, Graphics, Dialogs, ImgList, SynEdit, XMLCfg,
|
||||
DefineTemplates, CodeToolManager, CodeToolsOptions;
|
||||
|
||||
type
|
||||
@ -81,6 +81,19 @@ type
|
||||
InsertAsChildElseIfMenuItem: TMenuItem;
|
||||
InsertAsChildElseMenuItem: TMenuItem;
|
||||
DeleteNodeMenuItem: TMenuItem;
|
||||
ConvertActionMenuItem: TMenuItem;
|
||||
ConvertActionToDefineMenuItem: TMenuItem;
|
||||
ConvertActionToDefineRecurseMenuItem: TMenuItem;
|
||||
ConvertActionToUndefineMenuItem: TMenuItem;
|
||||
ConvertActionToUndefineRecurseMenuItem: TMenuItem;
|
||||
ConvertActionToUndefineAllMenuItem: TMenuItem;
|
||||
ConvertActionToBlockMenuItem: TMenuItem;
|
||||
ConvertActionToDirectoryMenuItem: TMenuItem;
|
||||
ConvertActionToIfMenuItem: TMenuItem;
|
||||
ConvertActionToIfDefMenuItem: TMenuItem;
|
||||
ConvertActionToIfNotDefMenuItem: TMenuItem;
|
||||
ConvertActionToElseIfMenuItem: TMenuItem;
|
||||
ConvertActionToElseMenuItem: TMenuItem;
|
||||
CopyToClipbrdMenuItem: TMenuItem;
|
||||
PasteFromClipbrdMenuItem: TMenuItem;
|
||||
|
||||
@ -137,6 +150,7 @@ type
|
||||
procedure MoveNodeLvlUpMenuItemClick(Sender: TObject);
|
||||
procedure MoveNodeLvlDownMenuItemClick(Sender: TObject);
|
||||
procedure DeleteNodeMenuItemClick(Sender: TObject);
|
||||
procedure ConvertActionMenuItemClick(Sender: TObject);
|
||||
private
|
||||
FDefineTree: TDefineTree;
|
||||
FLastSelectedNode: TTreeNode;
|
||||
@ -186,8 +200,37 @@ end;
|
||||
{ TCodeToolsDefinesEditor }
|
||||
|
||||
procedure TCodeToolsDefinesEditor.SaveAndExitMenuItemClick(Sender: TObject);
|
||||
var XMLConfig: TXMLConfig;
|
||||
t: TDefineTree;
|
||||
begin
|
||||
ModalResult:=mrOk;
|
||||
SaveSelectedValues(DefineTreeView.Selected);
|
||||
FLastSelectedNode:=nil;
|
||||
|
||||
t:=TDefineTree.Create;
|
||||
t.Assign(DefineTree);
|
||||
|
||||
writeln(' WWW TCodeToolsDefinesEditor.SaveAndExitMenuItemClick 0 ',t.IsEqual(DefineTree),' Consistency=',ConsistencyCheck);
|
||||
XMLConfig:=TXMLConfig.Create('/home/mattias/pascal/defines.xml');
|
||||
writeln(' WWW TCodeToolsDefinesEditor.SaveAndExitMenuItemClick A');
|
||||
DefineTree.SaveToXMLConfig(XMLConfig,'Globals/',dtspGlobals);
|
||||
writeln(' WWW TCodeToolsDefinesEditor.SaveAndExitMenuItemClick B');
|
||||
DefineTree.SaveToXMLConfig(XMLConfig,'Project/',dtspProjectSpecific);
|
||||
XMLConfig.Flush;
|
||||
|
||||
writeln(' WWW TCodeToolsDefinesEditor.SaveAndExitMenuItemClick C ');
|
||||
DefineTree.LoadFromXMLConfig(XMLConfig,'Globals/',dtlpGlobals,'Global');
|
||||
|
||||
writeln(' WWW TCodeToolsDefinesEditor.SaveAndExitMenuItemClick C ');
|
||||
DefineTree.LoadFromXMLConfig(XMLConfig,'Project/',dtlpProjectSpecific,'Project');
|
||||
|
||||
writeln(' WWW TCodeToolsDefinesEditor.SaveAndExitMenuItemClick D ',t.IsEqual(DefineTree),' Consistency=',ConsistencyCheck);
|
||||
RebuildDefineTreeView;
|
||||
|
||||
writeln(' WWW TCodeToolsDefinesEditor.SaveAndExitMenuItemClick END',' Consistency=',ConsistencyCheck);
|
||||
t.Free;
|
||||
XMLConfig.Free;
|
||||
|
||||
//ModalResult:=mrOk;
|
||||
end;
|
||||
|
||||
procedure TCodeToolsDefinesEditor.DontSaveAndExitMenuItemClick(Sender: TObject);
|
||||
@ -499,6 +542,37 @@ writeln(' AAA1 ',ConsistencyCheck);
|
||||
writeln(' AAA2 ',ConsistencyCheck);
|
||||
end;
|
||||
|
||||
procedure TCodeToolsDefinesEditor.ConvertActionMenuItemClick(Sender: TObject);
|
||||
var
|
||||
NewAction: TDefineAction;
|
||||
SelTreeNode: TTreeNode;
|
||||
SelDefNode: TDefineTemplate;
|
||||
begin
|
||||
SelTreeNode:=DefineTreeView.Selected;
|
||||
if SelTreeNode=nil then exit;
|
||||
SelDefNode:=TDefineTemplate(SelTreeNode.Data);
|
||||
if (SelDefNode.IsAutoGenerated) then begin
|
||||
MessageDlg('Node is readonly','Auto generated nodes can not be edited.',
|
||||
mtInformation,[mbCancel],0);
|
||||
exit;
|
||||
end;
|
||||
if Sender=ConvertActionToDefineMenuItem then NewAction:=da_Define
|
||||
else if Sender=ConvertActionToDefineRecurseMenuItem then NewAction:=da_DefineRecurse
|
||||
else if Sender=ConvertActionToUndefineMenuItem then NewAction:=da_Undefine
|
||||
else if Sender=ConvertActionToUndefineRecurseMenuItem then NewAction:=da_UndefineRecurse
|
||||
else if Sender=ConvertActionToUndefineAllMenuItem then NewAction:=da_UndefineAll
|
||||
else if Sender=ConvertActionToBlockMenuItem then NewAction:=da_Block
|
||||
else if Sender=ConvertActionToDirectoryMenuItem then NewAction:=da_Directory
|
||||
else if Sender=ConvertActionToIfMenuItem then NewAction:=da_If
|
||||
else if Sender=ConvertActionToIfDefMenuItem then NewAction:=da_IfDef
|
||||
else if Sender=ConvertActionToIfNotDefMenuItem then NewAction:=da_IfNDef
|
||||
else if Sender=ConvertActionToElseIfMenuItem then NewAction:=da_ElseIf
|
||||
else if Sender=ConvertActionToElseMenuItem then NewAction:=da_Else;
|
||||
SelDefNode.Action:=NewAction;
|
||||
SetNodeImages(SelTreeNode,false);
|
||||
SetTypeLabel;
|
||||
end;
|
||||
|
||||
procedure TCodeToolsDefinesEditor.ProjectSpecificCheckBoxClick(Sender: TObject);
|
||||
var
|
||||
SelTreeNode: TTreeNode;
|
||||
@ -616,15 +690,22 @@ begin
|
||||
MoveNodeLvlDownMenuItem.OnClick:=@MoveNodeLvlDownMenuItemClick;
|
||||
|
||||
EditMenuItem.Add(CreateSeperator);
|
||||
|
||||
AddMenuItem(InsertBehindMenuItem,'InsertBehindMenuItem','Insert node below',
|
||||
EditMenuItem);
|
||||
|
||||
AddMenuItem(InsertAsChildMenuItem,'InsertAsChildMenuItem','Insert node as child',
|
||||
EditMenuItem);
|
||||
|
||||
EditMenuItem.Add(CreateSeperator);
|
||||
|
||||
AddMenuItem(DeleteNodeMenuItem,'DeleteNodeMenuItem','Delete node',
|
||||
EditMenuItem);
|
||||
DeleteNodeMenuItem.OnClick:=@DeleteNodeMenuItemClick;
|
||||
|
||||
|
||||
AddMenuItem(ConvertActionMenuItem,'ConvertActionMenuItem','Convert node',
|
||||
EditMenuItem);
|
||||
|
||||
{ EditMenuItem.Add(CreateSeperator);
|
||||
AddMenuItem(CopyToClipbrdMenuItem,'CopyToClipbrdMenuItem','Copy to clipboard',
|
||||
EditMenuItem);
|
||||
@ -702,6 +783,42 @@ begin
|
||||
for i:=0 to InsertAsChildMenuItem.Count-1 do
|
||||
if InsertAsChildMenuItem[i].Caption<>'-' then
|
||||
InsertAsChildMenuItem[i].OnClick:=@InsertNodeMenuItemClick;
|
||||
|
||||
// convert node sub menu
|
||||
AddMenuItem(ConvertActionToDefineMenuItem,'ConvertActionToDefineMenuItem','Define',
|
||||
ConvertActionMenuItem);
|
||||
AddMenuItem(ConvertActionToDefineRecurseMenuItem,
|
||||
'ConvertActionToDefineRecurseMenuItem','Define Recurse',
|
||||
ConvertActionMenuItem);
|
||||
AddMenuItem(ConvertActionToUndefineMenuItem,
|
||||
'ConvertActionToUndefineMenuItem','Undefine',
|
||||
ConvertActionMenuItem);
|
||||
AddMenuItem(ConvertActionToUndefineRecurseMenuItem,
|
||||
'ConvertActionToUndefineRecurseMenuItem','Undefine Recurse',
|
||||
ConvertActionMenuItem);
|
||||
AddMenuItem(ConvertActionToUndefineAllMenuItem,
|
||||
'ConvertActionToUndefineAllMenuItem','Undefine All',
|
||||
ConvertActionMenuItem);
|
||||
ConvertActionMenuItem.Add(CreateSeperator);
|
||||
AddMenuItem(ConvertActionToBlockMenuItem,'ConvertActionToBlockMenuItem','Block',
|
||||
ConvertActionMenuItem);
|
||||
AddMenuItem(ConvertActionToDirectoryMenuItem,
|
||||
'ConvertActionToDirectoryMenuItem','Directory',
|
||||
ConvertActionMenuItem);
|
||||
ConvertActionMenuItem.Add(CreateSeperator);
|
||||
AddMenuItem(ConvertActionToIfMenuItem,'ConvertActionToIfMenuItem','If',
|
||||
ConvertActionMenuItem);
|
||||
AddMenuItem(ConvertActionToIfDefMenuItem,'ConvertActionToIfDefMenuItem','IfDef',
|
||||
ConvertActionMenuItem);
|
||||
AddMenuItem(ConvertActionToIfNotDefMenuItem,'ConvertActionToIfNotDefMenuItem','IfNDef',
|
||||
ConvertActionMenuItem);
|
||||
AddMenuItem(ConvertActionToElseIfMenuItem,'ConvertActionToElseIfMenuItem','ElseIf',
|
||||
ConvertActionMenuItem);
|
||||
AddMenuItem(ConvertActionToElseMenuItem,'ConvertActionToElseMenuItem','Else',
|
||||
ConvertActionMenuItem);
|
||||
for i:=0 to ConvertActionMenuItem.Count-1 do
|
||||
if ConvertActionMenuItem[i].Caption<>'-' then
|
||||
ConvertActionMenuItem[i].OnClick:=@ConvertActionMenuItemClick;
|
||||
|
||||
// tools
|
||||
{ AddMenuItem(ToolsMenuItem,'ToolsMenuItem','Tools',nil);
|
||||
@ -1106,11 +1223,11 @@ function TCodeToolsDefinesEditor.ConsistencyCheck: integer;
|
||||
writeln('ATreeNode.GetNextSibling.Next=',DummyDefNode.Name)
|
||||
else
|
||||
writeln('ATreeNode.GetNextSibling.Next=nil');
|
||||
writeln('=============================================');
|
||||
{writeln('=============================================');
|
||||
DefineTreeView.WriteDebugReport('TV ',true);
|
||||
writeln('=============================================');
|
||||
DefineTree.WriteDebugReport;
|
||||
writeln('=============================================');
|
||||
writeln('=============================================');}
|
||||
Result:=-3; exit;
|
||||
end;
|
||||
if (ATreeNode.GetFirstChild<>nil)
|
||||
|
Loading…
Reference in New Issue
Block a user