mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 17:19:19 +02:00
MG: fixed a node cache range bug
git-svn-id: trunk@1435 -
This commit is contained in:
parent
2a0d19493f
commit
c2bcc86b61
@ -178,18 +178,22 @@ type
|
|||||||
var NewX, NewY, NewTopLine: integer): boolean;
|
var NewX, NewY, NewTopLine: integer): boolean;
|
||||||
|
|
||||||
// functions for events in the object inspector
|
// functions for events in the object inspector
|
||||||
function GetCompatibleMethods(Code: TCodeBuffer; const AClassName: string;
|
function GetCompatiblePublishedMethods(Code: TCodeBuffer;
|
||||||
TypeData: PTypeData; Proc: TGetStringProc): boolean;
|
const AClassName: string; TypeData: PTypeData;
|
||||||
function MethodExists(Code:TCodeBuffer; const AClassName,
|
Proc: TGetStringProc): boolean;
|
||||||
AMethodName: string; TypeData: PTypeData): boolean;
|
function PublishedMethodExists(Code:TCodeBuffer; const AClassName,
|
||||||
function JumpToMethodBody(Code: TCodeBuffer;
|
AMethodName: string; TypeData: PTypeData;
|
||||||
|
var MethodIsCompatible, MethodIsPublished, IdentIsMethod: boolean
|
||||||
|
): boolean;
|
||||||
|
function JumpToPublishedMethodBody(Code: TCodeBuffer;
|
||||||
const AClassName, AMethodName: string; TypeData: PTypeData;
|
const AClassName, AMethodName: string; TypeData: PTypeData;
|
||||||
var NewCode: TCodeBuffer;
|
var NewCode: TCodeBuffer;
|
||||||
var NewX, NewY, NewTopLine: integer): boolean;
|
var NewX, NewY, NewTopLine: integer): boolean;
|
||||||
function RenameMethod(Code: TCodeBuffer; const AClassName, OldMethodName,
|
function RenamePublishedMethod(Code: TCodeBuffer;
|
||||||
NewMethodName: string; TypeData: PTypeData): boolean;
|
const AClassName, OldMethodName,
|
||||||
function CreateMethod(Code: TCodeBuffer; const AClassName,
|
NewMethodName: string): boolean;
|
||||||
NewMethodName: string; TypeData: PTypeData): boolean;
|
function CreatePublishedMethod(Code: TCodeBuffer; const AClassName,
|
||||||
|
NewMethodName: string; ATypeInfo: PTypeInfo): boolean;
|
||||||
|
|
||||||
// code completion = auto class completion, auto forward proc completion
|
// code completion = auto class completion, auto forward proc completion
|
||||||
function CompleteCode(Code: TCodeBuffer; X,Y: integer;
|
function CompleteCode(Code: TCodeBuffer; X,Y: integer;
|
||||||
@ -712,11 +716,11 @@ writeln('TCodeToolManager.GuessUnclosedBlock END ');
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCodeToolManager.GetCompatibleMethods(Code: TCodeBuffer;
|
function TCodeToolManager.GetCompatiblePublishedMethods(Code: TCodeBuffer;
|
||||||
const AClassName: string; TypeData: PTypeData; Proc: TGetStringProc): boolean;
|
const AClassName: string; TypeData: PTypeData; Proc: TGetStringProc): boolean;
|
||||||
begin
|
begin
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
writeln('TCodeToolManager.GetCompatibleMethods A ',Code.Filename,' Classname=',AClassname);
|
writeln('TCodeToolManager.GetCompatiblePublishedMethods A ',Code.Filename,' Classname=',AClassname);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Result:=InitCurCodeTool(Code);
|
Result:=InitCurCodeTool(Code);
|
||||||
if not InitCurCodeTool(Code) then exit;
|
if not InitCurCodeTool(Code) then exit;
|
||||||
@ -728,29 +732,31 @@ writeln('TCodeToolManager.GetCompatibleMethods A ',Code.Filename,' Classname=',A
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCodeToolManager.MethodExists(Code:TCodeBuffer;
|
function TCodeToolManager.PublishedMethodExists(Code:TCodeBuffer;
|
||||||
const AClassName, AMethodName: string; TypeData: PTypeData): boolean;
|
const AClassName, AMethodName: string; TypeData: PTypeData;
|
||||||
|
var MethodIsCompatible, MethodIsPublished, IdentIsMethod: boolean): boolean;
|
||||||
begin
|
begin
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
writeln('TCodeToolManager.MethodExists A ',Code.Filename,' ',AClassName,':',AMethodName);
|
writeln('TCodeToolManager.PublishedMethodExists A ',Code.Filename,' ',AClassName,':',AMethodName);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Result:=InitCurCodeTool(Code);
|
Result:=InitCurCodeTool(Code);
|
||||||
if not Result then exit;
|
if not Result then exit;
|
||||||
try
|
try
|
||||||
Result:=FCurCodeTool.PublishedMethodExists(UpperCaseStr(AClassName),
|
Result:=FCurCodeTool.PublishedMethodExists(UpperCaseStr(AClassName),
|
||||||
UpperCaseStr(AMethodName),TypeData);
|
UpperCaseStr(AMethodName),TypeData,
|
||||||
|
MethodIsCompatible,MethodIsPublished,IdentIsMethod);
|
||||||
except
|
except
|
||||||
on e: Exception do Result:=HandleException(e);
|
on e: Exception do Result:=HandleException(e);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCodeToolManager.JumpToMethodBody(Code: TCodeBuffer;
|
function TCodeToolManager.JumpToPublishedMethodBody(Code: TCodeBuffer;
|
||||||
const AClassName, AMethodName: string; TypeData: PTypeData;
|
const AClassName, AMethodName: string; TypeData: PTypeData;
|
||||||
var NewCode: TCodeBuffer; var NewX, NewY, NewTopLine: integer): boolean;
|
var NewCode: TCodeBuffer; var NewX, NewY, NewTopLine: integer): boolean;
|
||||||
var NewPos: TCodeXYPosition;
|
var NewPos: TCodeXYPosition;
|
||||||
begin
|
begin
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
writeln('TCodeToolManager.JumpToMethodBody A ',Code.Filename,' ',AClassName,':',AMethodName);
|
writeln('TCodeToolManager.JumpToPublishedMethodBody A ',Code.Filename,' ',AClassName,':',AMethodName);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Result:=InitCurCodeTool(Code);
|
Result:=InitCurCodeTool(Code);
|
||||||
if not Result then exit;
|
if not Result then exit;
|
||||||
@ -767,36 +773,36 @@ writeln('TCodeToolManager.JumpToMethodBody A ',Code.Filename,' ',AClassName,':',
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCodeToolManager.RenameMethod(Code: TCodeBuffer; const AClassName,
|
function TCodeToolManager.RenamePublishedMethod(Code: TCodeBuffer;
|
||||||
OldMethodName, NewMethodName: string; TypeData: PTypeData): boolean;
|
const AClassName, OldMethodName, NewMethodName: string): boolean;
|
||||||
begin
|
begin
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
writeln('TCodeToolManager.RenameMethod A');
|
writeln('TCodeToolManager.RenamePublishedMethod A');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Result:=InitCurCodeTool(Code);
|
Result:=InitCurCodeTool(Code);
|
||||||
if not Result then exit;
|
if not Result then exit;
|
||||||
try
|
try
|
||||||
SourceChangeCache.Clear;
|
SourceChangeCache.Clear;
|
||||||
Result:=FCurCodeTool.RenamePublishedMethod(UpperCaseStr(AClassName),
|
Result:=FCurCodeTool.RenamePublishedMethod(UpperCaseStr(AClassName),
|
||||||
UpperCaseStr(OldMethodName),NewMethodName,TypeData,
|
UpperCaseStr(OldMethodName),NewMethodName,
|
||||||
SourceChangeCache);
|
SourceChangeCache);
|
||||||
except
|
except
|
||||||
on e: Exception do Result:=HandleException(e);
|
on e: Exception do Result:=HandleException(e);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCodeToolManager.CreateMethod(Code: TCodeBuffer; const AClassName,
|
function TCodeToolManager.CreatePublishedMethod(Code: TCodeBuffer;
|
||||||
NewMethodName: string; TypeData: PTypeData): boolean;
|
const AClassName, NewMethodName: string; ATypeInfo: PTypeInfo): boolean;
|
||||||
begin
|
begin
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
writeln('TCodeToolManager.CreateMethod A');
|
writeln('TCodeToolManager.CreatePublishedMethod A');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Result:=InitCurCodeTool(Code);
|
Result:=InitCurCodeTool(Code);
|
||||||
if not Result then exit;
|
if not Result then exit;
|
||||||
try
|
try
|
||||||
SourceChangeCache.Clear;
|
SourceChangeCache.Clear;
|
||||||
Result:=FCurCodeTool.CreatePublishedMethod(UpperCaseStr(AClassName),
|
Result:=FCurCodeTool.CreatePublishedMethod(UpperCaseStr(AClassName),
|
||||||
NewMethodName,TypeData,SourceChangeCache);
|
NewMethodName,ATypeInfo,SourceChangeCache);
|
||||||
except
|
except
|
||||||
on e: Exception do Result:=HandleException(e);
|
on e: Exception do Result:=HandleException(e);
|
||||||
end;
|
end;
|
||||||
@ -1385,11 +1391,17 @@ begin
|
|||||||
FWriteLockStep:=-$7fffffff;
|
FWriteLockStep:=-$7fffffff;
|
||||||
end;
|
end;
|
||||||
inc(FWriteLockCount);
|
inc(FWriteLockCount);
|
||||||
|
{$IFDEF CTDEBUG}
|
||||||
|
writeln('[TCodeToolManager.ActivateWriteLock] FWriteLockCount=',FWriteLockCount,' FWriteLockStep=',FWriteLockStep);
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCodeToolManager.DeactivateWriteLock;
|
procedure TCodeToolManager.DeactivateWriteLock;
|
||||||
begin
|
begin
|
||||||
if FWriteLockCount>0 then dec(FWriteLockCount);
|
if FWriteLockCount>0 then dec(FWriteLockCount);
|
||||||
|
{$IFDEF CTDEBUG}
|
||||||
|
writeln('[TCodeToolManager.DeactivateWriteLock] FWriteLockCount=',FWriteLockCount,' FWriteLockStep=',FWriteLockStep);
|
||||||
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCodeToolManager.OnToolGetWriteLockInfo(var WriteLockIsSet: boolean;
|
procedure TCodeToolManager.OnToolGetWriteLockInfo(var WriteLockIsSet: boolean;
|
||||||
|
@ -52,6 +52,8 @@ type
|
|||||||
GetCompatibleMethodsProc: TGetStringProc;
|
GetCompatibleMethodsProc: TGetStringProc;
|
||||||
SearchedExprList: TExprTypeList;
|
SearchedExprList: TExprTypeList;
|
||||||
SearchedCompatibilityList: TTypeCompatibilityList;
|
SearchedCompatibilityList: TTypeCompatibilityList;
|
||||||
|
function FindIdentifierNodeInClass(ClassNode: TCodeTreeNode;
|
||||||
|
Identifier: PChar): TCodeTreeNode;
|
||||||
protected
|
protected
|
||||||
function InsertNewMethodToClass(ClassSectionNode: TCodeTreeNode;
|
function InsertNewMethodToClass(ClassSectionNode: TCodeTreeNode;
|
||||||
const AMethodName,NewMethod: string;
|
const AMethodName,NewMethod: string;
|
||||||
@ -64,23 +66,26 @@ type
|
|||||||
function GetCompatiblePublishedMethods(ClassNode: TCodeTreeNode;
|
function GetCompatiblePublishedMethods(ClassNode: TCodeTreeNode;
|
||||||
TypeData: PTypeData; Proc: TGetStringProc): boolean;
|
TypeData: PTypeData; Proc: TGetStringProc): boolean;
|
||||||
function PublishedMethodExists(const UpperClassName,
|
function PublishedMethodExists(const UpperClassName,
|
||||||
UpperMethodName: string; TypeData: PTypeData): boolean;
|
UpperMethodName: string; TypeData: PTypeData;
|
||||||
|
var MethodIsCompatible, MethodIsPublished, IdentIsMethod: boolean
|
||||||
|
): boolean;
|
||||||
function PublishedMethodExists(ClassNode: TCodeTreeNode;
|
function PublishedMethodExists(ClassNode: TCodeTreeNode;
|
||||||
const UpperMethodName: string; TypeData: PTypeData): boolean;
|
const UpperMethodName: string; TypeData: PTypeData;
|
||||||
|
var MethodIsCompatible, MethodIsPublished, IdentIsMethod: boolean
|
||||||
|
): boolean;
|
||||||
function JumpToPublishedMethodBody(const UpperClassName,
|
function JumpToPublishedMethodBody(const UpperClassName,
|
||||||
UpperMethodName: string; TypeData: PTypeData;
|
UpperMethodName: string; TypeData: PTypeData;
|
||||||
var NewPos: TCodeXYPosition; var NewTopLine: integer): boolean;
|
var NewPos: TCodeXYPosition; var NewTopLine: integer): boolean;
|
||||||
function RenamePublishedMethod(const UpperClassName, UpperOldMethodName,
|
function RenamePublishedMethod(const UpperClassName, UpperOldMethodName,
|
||||||
NewMethodName: string; TypeData: PTypeData;
|
NewMethodName: string; SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
|
||||||
function RenamePublishedMethod(ClassNode: TCodeTreeNode;
|
function RenamePublishedMethod(ClassNode: TCodeTreeNode;
|
||||||
const UpperOldMethodName, NewMethodName: string; TypeData: PTypeData;
|
const UpperOldMethodName, NewMethodName: string;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
function CreatePublishedMethod(const UpperClassName,
|
function CreatePublishedMethod(const UpperClassName,
|
||||||
AMethodName: string; TypeData: PTypeData;
|
AMethodName: string; ATypeInfo: PTypeInfo;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
function CreatePublishedMethod(ClassNode: TCodeTreeNode;
|
function CreatePublishedMethod(ClassNode: TCodeTreeNode;
|
||||||
const AMethodName: string; TypeData: PTypeData;
|
const AMethodName: string; ATypeInfo: PTypeInfo;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
|
|
||||||
function MethodTypeDataToStr(TypeData: PTypeData;
|
function MethodTypeDataToStr(TypeData: PTypeData;
|
||||||
@ -88,10 +93,10 @@ type
|
|||||||
function CreateExprListFromMethodTypeData(TypeData: PTypeData;
|
function CreateExprListFromMethodTypeData(TypeData: PTypeData;
|
||||||
Params: TFindDeclarationParams): TExprTypeList;
|
Params: TFindDeclarationParams): TExprTypeList;
|
||||||
function FindPublishedMethodNodeInClass(ClassNode: TCodeTreeNode;
|
function FindPublishedMethodNodeInClass(ClassNode: TCodeTreeNode;
|
||||||
const UpperMethodName: string; TypeData: PTypeData): TCodeTreeNode;
|
const UpperMethodName: string): TFindContext;
|
||||||
function FindProcNodeInImplementation(const UpperClassName,
|
function FindProcNodeInImplementation(const UpperClassName,
|
||||||
UpperMethodName: string; TypeData: PTypeData;
|
UpperMethodName: string; BuildTreeBefore: boolean): TCodeTreeNode;
|
||||||
BuildTreeBefore: boolean): TCodeTreeNode;
|
function MethodTypeInfoToStr(ATypeInfo: PTypeInfo): string;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -204,9 +209,7 @@ end;
|
|||||||
|
|
||||||
function TEventsCodeTool.GetCompatiblePublishedMethods(
|
function TEventsCodeTool.GetCompatiblePublishedMethods(
|
||||||
ClassNode: TCodeTreeNode; TypeData: PTypeData; Proc: TGetStringProc): boolean;
|
ClassNode: TCodeTreeNode; TypeData: PTypeData; Proc: TGetStringProc): boolean;
|
||||||
var //SearchedProc: string;
|
var
|
||||||
//SectionNode, ANode: TCodeTreeNode;
|
|
||||||
//CurProcHead, CurProcName: string;
|
|
||||||
Params: TFindDeclarationParams;
|
Params: TFindDeclarationParams;
|
||||||
CompListSize: integer;
|
CompListSize: integer;
|
||||||
begin
|
begin
|
||||||
@ -255,109 +258,63 @@ writeln('[TEventsCodeTool.GetCompatiblePublishedMethods]');
|
|||||||
finally
|
finally
|
||||||
DeactivateGlobalWriteLock;
|
DeactivateGlobalWriteLock;
|
||||||
end;
|
end;
|
||||||
{
|
|
||||||
SearchedProc:=MethodTypeDataToStr(TypeData,[phpInUpperCase]);
|
|
||||||
SectionNode:=ClassNode.FirstChild;
|
|
||||||
while (SectionNode<>nil) do begin
|
|
||||||
while (SectionNode.Desc<>ctnClassPublished) or (SectionNode.FirstChild=nil)
|
|
||||||
do begin
|
|
||||||
SectionNode:=SectionNode.NextBrother;
|
|
||||||
if SectionNode=nil then exit;
|
|
||||||
end;
|
|
||||||
ANode:=SectionNode.FirstChild;
|
|
||||||
repeat
|
|
||||||
if (ANode.Desc=ctnProcedure) then begin
|
|
||||||
CurProcHead:=ExtractProcHead(ANode,[phpInUpperCase,phpWithoutName]);
|
|
||||||
if (CurProcHead<>'')
|
|
||||||
and (CompareTextIgnoringSpace(CurProcHead,SearchedProc,true)=0) then
|
|
||||||
begin
|
|
||||||
CurProcName:=ExtractProcName(ANode,false);
|
|
||||||
if (CurProcName<>'') and (length(CurProcName)<256) then
|
|
||||||
Proc(CurProcName);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
ANode:=ANode.NextBrother;
|
|
||||||
until ANode=nil;
|
|
||||||
SectionNode:=SectionNode.NextBrother;
|
|
||||||
end;
|
|
||||||
}
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEventsCodeTool.FindPublishedMethodNodeInClass(
|
function TEventsCodeTool.FindPublishedMethodNodeInClass(
|
||||||
ClassNode: TCodeTreeNode; const UpperMethodName: string;
|
ClassNode: TCodeTreeNode; const UpperMethodName: string): TFindContext;
|
||||||
TypeData: PTypeData): TCodeTreeNode;
|
|
||||||
var
|
var
|
||||||
SectionNode, ANode: TCodeTreeNode;
|
Params: TFindDeclarationParams;
|
||||||
SearchedProcHead, CurProcHead: string;
|
|
||||||
begin
|
begin
|
||||||
Result:=nil;
|
Result:=CleanFindContext;
|
||||||
if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) or (UpperMethodName='')
|
if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) or (UpperMethodName='')
|
||||||
or (Scanner=nil) or (TypeData=nil) then exit;
|
or (Scanner=nil) then exit;
|
||||||
SearchedProcHead:=UpperMethodName+MethodTypeDataToStr(TypeData,
|
ActivateGlobalWriteLock;
|
||||||
[phpInUpperCase]);
|
try
|
||||||
{$IFDEF CTDEBUG}
|
Params:=TFindDeclarationParams.Create;
|
||||||
writeln('TEventsCodeTool.FindPublishedMethodNodeInClass A SearchedProcHead="',
|
try
|
||||||
SearchedProcHead,'"');
|
Params.ContextNode:=ClassNode;
|
||||||
{$ENDIF}
|
Params.SetIdentifier(Self,@UpperMethodName[1],nil);
|
||||||
BuildSubTreeForClass(ClassNode);
|
Params.Flags:=[fdfSearchInAncestors,fdfClassPublished];
|
||||||
SectionNode:=ClassNode.FirstChild;
|
if FindIdentifierInContext(Params)
|
||||||
while (SectionNode<>nil) do begin
|
and (Params.NewNode.Desc=ctnProcedure) then begin
|
||||||
while (SectionNode.Desc<>ctnClassPublished) or (SectionNode.FirstChild=nil)
|
Result:=CreateFindContext(Params);
|
||||||
do begin
|
|
||||||
SectionNode:=SectionNode.NextBrother;
|
|
||||||
if SectionNode=nil then exit;
|
|
||||||
end;
|
|
||||||
ANode:=SectionNode.FirstChild;
|
|
||||||
repeat
|
|
||||||
if (ANode.Desc=ctnProcedure) then begin
|
|
||||||
CurProcHead:=ExtractProcHead(ANode,[phpInUpperCase]);
|
|
||||||
{$IFDEF CTDEBUG}
|
|
||||||
writeln('TEventsCodeTool.FindPublishedMethodNodeInClass "',SearchedProcHead,
|
|
||||||
'"="',CurProcHead,'"');
|
|
||||||
{$ENDIF}
|
|
||||||
if (CurProcHead<>'')
|
|
||||||
and (CompareTextIgnoringSpace(CurProcHead,SearchedProcHead,true)=0) then
|
|
||||||
begin
|
|
||||||
Result:=ANode;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
ANode:=ANode.NextBrother;
|
finally
|
||||||
until ANode=nil;
|
Params.Free;
|
||||||
SectionNode:=SectionNode.NextBrother;
|
end;
|
||||||
|
finally
|
||||||
|
DeactivateGlobalWriteLock;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEventsCodeTool.FindProcNodeInImplementation(const UpperClassName,
|
function TEventsCodeTool.FindProcNodeInImplementation(const UpperClassName,
|
||||||
UpperMethodName: string; TypeData: PTypeData;
|
UpperMethodName: string; BuildTreeBefore: boolean): TCodeTreeNode;
|
||||||
BuildTreeBefore: boolean): TCodeTreeNode;
|
|
||||||
var SectionNode, ANode: TCodeTreeNode;
|
var SectionNode, ANode: TCodeTreeNode;
|
||||||
SearchedProcHead, CurProcHead: string;
|
|
||||||
begin
|
begin
|
||||||
Result:=nil;
|
Result:=nil;
|
||||||
|
if (UpperMethodName='') or (UpperClassName='') then exit;
|
||||||
if BuildTreeBefore then BuildTree(false);
|
if BuildTreeBefore then BuildTree(false);
|
||||||
// find implementation node
|
// find implementation node
|
||||||
SectionNode:=Tree.Root;
|
SectionNode:=FindImplementationNode;
|
||||||
while (SectionNode<>nil) and (SectionNode.Desc<>ctnImplementation) do
|
|
||||||
SectionNode:=SectionNode.NextBrother;
|
|
||||||
if SectionNode=nil then exit;
|
if SectionNode=nil then exit;
|
||||||
ANode:=SectionNode.FirstChild;
|
ANode:=SectionNode.FirstChild;
|
||||||
SearchedProcHead:=UpperClassName+'.'+UpperMethodName
|
|
||||||
+MethodTypeDataToStr(TypeData,[phpInUpperCase,phpWithParameterNames]);
|
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
writeln('[TEventsCodeTool.FindProcNodeInImplementation] SearchedProcHead=',SearchedProcHead);
|
writeln('[TEventsCodeTool.FindProcNodeInImplementation] A');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
while (ANode<>nil) do begin
|
while (ANode<>nil) do begin
|
||||||
if (ANode.Desc=ctnProcedure) then begin
|
if (ANode.Desc=ctnProcedure) and (ANode.FirstChild<>nil)
|
||||||
CurProcHead:=ExtractProcHead(ANode,[phpInUpperCase]);
|
and CompareSrcIdentifiers(ANode.FirstChild.StartPos,@UpperClassName[1])
|
||||||
{$IFDEF CTDEBUG}
|
then begin
|
||||||
writeln('[TEventsCodeTool.FindProcNodeInImplementation] CurProcHead=',CurProcHead);
|
MoveCursorToNodeStart(ANode.FirstChild);
|
||||||
{$ENDIF}
|
ReadNextAtom; // read class name
|
||||||
if (CurProcHead<>'')
|
ReadNextAtom; // read '.'
|
||||||
and (CompareTextIgnoringSpace(CurProcHead,SearchedProcHead,true)=0) then
|
if AtomIsChar('.') then begin
|
||||||
begin
|
ReadNextAtom;
|
||||||
Result:=ANode;
|
if CompareSrcIdentifiers(CurPos.StartPos,@UpperMethodName[1]) then
|
||||||
exit;
|
begin
|
||||||
|
Result:=ANode;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
ANode:=ANode.NextBrother;
|
ANode:=ANode.NextBrother;
|
||||||
@ -365,20 +322,95 @@ writeln('[TEventsCodeTool.FindProcNodeInImplementation] CurProcHead=',CurProcHea
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TEventsCodeTool.PublishedMethodExists(const UpperClassName,
|
function TEventsCodeTool.PublishedMethodExists(const UpperClassName,
|
||||||
UpperMethodName: string; TypeData: PTypeData): boolean;
|
UpperMethodName: string; TypeData: PTypeData;
|
||||||
|
var MethodIsCompatible, MethodIsPublished, IdentIsMethod: boolean): boolean;
|
||||||
var ClassNode: TCodeTreeNode;
|
var ClassNode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
BuildTree(true);
|
ActivateGlobalWriteLock;
|
||||||
if not InterfaceSectionFound then exit;
|
try
|
||||||
ClassNode:=FindClassNodeInInterface(UpperClassName,true,false);
|
{$IFDEF CTDEBUG}
|
||||||
Result:=PublishedMethodExists(ClassNode,UpperMethodName,TypeData);
|
writeln('[TEventsCodeTool.PublishedMethodExists] A UpperClassName=',UpperClassName);
|
||||||
|
{$ENDIF}
|
||||||
|
BuildTree(true);
|
||||||
|
if not InterfaceSectionFound then exit;
|
||||||
|
ClassNode:=FindClassNodeInInterface(UpperClassName,true,false);
|
||||||
|
{$IFDEF CTDEBUG}
|
||||||
|
writeln('[TEventsCodeTool.PublishedMethodExists] B ',ClassNode<>nil);
|
||||||
|
{$ENDIF}
|
||||||
|
Result:=PublishedMethodExists(ClassNode,UpperMethodName,TypeData,
|
||||||
|
MethodIsCompatible,MethodIsPublished,IdentIsMethod);
|
||||||
|
finally
|
||||||
|
DeactivateGlobalWriteLock;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEventsCodeTool.PublishedMethodExists(ClassNode: TCodeTreeNode;
|
function TEventsCodeTool.PublishedMethodExists(ClassNode: TCodeTreeNode;
|
||||||
const UpperMethodName: string; TypeData: PTypeData): boolean;
|
const UpperMethodName: string; TypeData: PTypeData;
|
||||||
|
var MethodIsCompatible, MethodIsPublished, IdentIsMethod: boolean): boolean;
|
||||||
|
var
|
||||||
|
FoundContext: TFindContext;
|
||||||
|
CompListSize: integer;
|
||||||
|
ParamCompatibility: TTypeCompatibility;
|
||||||
|
FirstParameterNode: TCodeTreeNode;
|
||||||
|
Params: TFindDeclarationParams;
|
||||||
begin
|
begin
|
||||||
Result:=(FindPublishedMethodNodeInClass(ClassNode,UpperMethodName,TypeData)
|
Result:=false;
|
||||||
<>nil);
|
MethodIsCompatible:=false;
|
||||||
|
IdentIsmethod:=false;
|
||||||
|
MethodIsPublished:=false;
|
||||||
|
ActivateGlobalWriteLock;
|
||||||
|
try
|
||||||
|
Params:=TFindDeclarationParams.Create;
|
||||||
|
try
|
||||||
|
// first search a published method definition with same name
|
||||||
|
Params.ContextNode:=ClassNode;
|
||||||
|
Params.SetIdentifier(Self,@UpperMethodName[1],nil);
|
||||||
|
Params.Flags:=[fdfSearchInAncestors,fdfClassPublished];
|
||||||
|
if FindIdentifierInContext(Params) then begin
|
||||||
|
IdentIsmethod:=(Params.NewNode.Desc=ctnProcedure);
|
||||||
|
MethodIsPublished:=(Params.NewNode.Parent.Desc=ctnClassPublished);
|
||||||
|
if IdentIsmethod and MethodIsPublished then begin
|
||||||
|
// published method with same name found
|
||||||
|
FoundContext:=CreateFindContext(Params);
|
||||||
|
// -> test for compatibility
|
||||||
|
|
||||||
|
// convert the TypeData to an expression type list
|
||||||
|
Params.ContextNode:=Params.NewNode;
|
||||||
|
SearchedExprList:=CreateExprListFromMethodTypeData(TypeData,Params);
|
||||||
|
// create compatibility list
|
||||||
|
CompListSize:=SizeOf(TTypeCompatibility)*SearchedExprList.Count;
|
||||||
|
if CompListSize>0 then begin
|
||||||
|
GetMem(SearchedCompatibilityList,CompListSize);
|
||||||
|
end else begin
|
||||||
|
SearchedCompatibilityList:=nil;
|
||||||
|
end;
|
||||||
|
try
|
||||||
|
// check for compatibility
|
||||||
|
FirstParameterNode:=FoundContext.Tool.GetFirstParameterNode(
|
||||||
|
FoundContext.Node);
|
||||||
|
ParamCompatibility:=FoundContext.Tool.IsParamListCompatible(
|
||||||
|
FirstParameterNode,
|
||||||
|
SearchedExprList,false,
|
||||||
|
Params,SearchedCompatibilityList);
|
||||||
|
if ParamCompatibility=tcExact then begin
|
||||||
|
MethodIsCompatible:=true;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
SearchedExprList.Free;
|
||||||
|
SearchedExprList:=nil;
|
||||||
|
if SearchedCompatibilityList<>nil then
|
||||||
|
FreeMem(SearchedCompatibilityList);
|
||||||
|
SearchedCompatibilityList:=nil;
|
||||||
|
end;
|
||||||
|
Result:=true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
Params.Free;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
DeactivateGlobalWriteLock;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEventsCodeTool.JumpToPublishedMethodBody(const UpperClassName,
|
function TEventsCodeTool.JumpToPublishedMethodBody(const UpperClassName,
|
||||||
@ -387,13 +419,12 @@ function TEventsCodeTool.JumpToPublishedMethodBody(const UpperClassName,
|
|||||||
var ANode: TCodeTreeNode;
|
var ANode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
ANode:=FindProcNodeInImplementation(UpperClassName,UpperMethodName,TypeData,
|
ANode:=FindProcNodeInImplementation(UpperClassName,UpperMethodName,true);
|
||||||
true);
|
|
||||||
Result:=FindJumpPointInProcNode(ANode,NewPos,NewTopLine);
|
Result:=FindJumpPointInProcNode(ANode,NewPos,NewTopLine);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEventsCodeTool.RenamePublishedMethod(const UpperClassName,
|
function TEventsCodeTool.RenamePublishedMethod(const UpperClassName,
|
||||||
UpperOldMethodName, NewMethodName: string; TypeData: PTypeData;
|
UpperOldMethodName, NewMethodName: string;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
var ClassNode: TCodeTreeNode;
|
var ClassNode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
@ -401,12 +432,12 @@ begin
|
|||||||
if not EndOfSourceFound then exit;
|
if not EndOfSourceFound then exit;
|
||||||
ClassNode:=FindClassNodeInInterface(UpperClassName,true,false);
|
ClassNode:=FindClassNodeInInterface(UpperClassName,true,false);
|
||||||
Result:=RenamePublishedMethod(ClassNode,UpperOldMethodName,NewMethodName,
|
Result:=RenamePublishedMethod(ClassNode,UpperOldMethodName,NewMethodName,
|
||||||
TypeData,SourceChangeCache);
|
SourceChangeCache);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEventsCodeTool.RenamePublishedMethod(ClassNode: TCodeTreeNode;
|
function TEventsCodeTool.RenamePublishedMethod(ClassNode: TCodeTreeNode;
|
||||||
const UpperOldMethodName, NewMethodName: string; TypeData: PTypeData;
|
const UpperOldMethodName, NewMethodName: string;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
// rename published method in class and in procedure itself
|
// rename published method in class and in procedure itself
|
||||||
var ANode, ProcHeadNode: TCodeTreeNode;
|
var ANode, ProcHeadNode: TCodeTreeNode;
|
||||||
NameStart, NameEnd: integer;
|
NameStart, NameEnd: integer;
|
||||||
@ -414,15 +445,19 @@ var ANode, ProcHeadNode: TCodeTreeNode;
|
|||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) or (UpperOldMethodName='')
|
if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) or (UpperOldMethodName='')
|
||||||
or (NewMethodName='') or (SourceChangeCache=nil) or (Scanner=nil)
|
or (NewMethodName='') or (SourceChangeCache=nil) or (Scanner=nil) then
|
||||||
or (TypeData=nil) then exit;
|
exit;
|
||||||
SourceChangeCache.MainScanner:=Scanner;
|
SourceChangeCache.MainScanner:=Scanner;
|
||||||
// rename in class
|
// rename in class
|
||||||
ANode:=FindPublishedMethodNodeInClass(ClassNode,UpperOldMethodName,TypeData);
|
ANode:=FindIdentifierNodeInClass(ClassNode,@UpperOldMethodName[1]);
|
||||||
{$IFDEF CTDEBUG}
|
if (ANode=nil) then begin
|
||||||
writeln('TEventsCodeTool.RenamePublishedMethod A ',ANode<>nil);
|
MoveCursorToNodeStart(ClassNode);
|
||||||
{$ENDIF}
|
RaiseException('old method not found: '+UpperOldMethodName);
|
||||||
if ANode=nil then exit;
|
end;
|
||||||
|
if (ANode.Desc<>ctnProcedure) then begin
|
||||||
|
MoveCursorToNodeStart(ANode);
|
||||||
|
RaiseException('old method not found: '+UpperOldMethodName);
|
||||||
|
end;
|
||||||
ProcHeadNode:=ANode.FirstChild;
|
ProcHeadNode:=ANode.FirstChild;
|
||||||
if ProcHeadNode=nil then exit;
|
if ProcHeadNode=nil then exit;
|
||||||
NameStart:=ProcHeadNode.StartPos;
|
NameStart:=ProcHeadNode.StartPos;
|
||||||
@ -433,14 +468,7 @@ writeln('TEventsCodeTool.RenamePublishedMethod A ',ANode<>nil);
|
|||||||
NewMethodName) then exit;
|
NewMethodName) then exit;
|
||||||
// rename procedure itself -> find implementation node
|
// rename procedure itself -> find implementation node
|
||||||
UpperClassName:=ExtractClassName(ClassNode,true);
|
UpperClassName:=ExtractClassName(ClassNode,true);
|
||||||
{$IFDEF CTDEBUG}
|
ANode:=FindProcNodeInImplementation(UpperClassName,UpperOldMethodName,false);
|
||||||
writeln('TEventsCodeTool.RenamePublishedMethod B ClassName=',UpperClassName);
|
|
||||||
{$ENDIF}
|
|
||||||
ANode:=FindProcNodeInImplementation(UpperClassName,UpperOldMethodName,
|
|
||||||
TypeData,false);
|
|
||||||
{$IFDEF CTDEBUG}
|
|
||||||
writeln('TEventsCodeTool.RenamePublishedMethod C ',ANode<>nil);
|
|
||||||
{$ENDIF}
|
|
||||||
if ANode=nil then exit;
|
if ANode=nil then exit;
|
||||||
ProcHeadNode:=ANode.FirstChild;
|
ProcHeadNode:=ANode.FirstChild;
|
||||||
if ProcHeadNode=nil then exit;
|
if ProcHeadNode=nil then exit;
|
||||||
@ -448,50 +476,62 @@ writeln('TEventsCodeTool.RenamePublishedMethod C ',ANode<>nil);
|
|||||||
ReadNextAtom; // read class name
|
ReadNextAtom; // read class name
|
||||||
ReadNextAtom; // read '.'
|
ReadNextAtom; // read '.'
|
||||||
ReadNextAtom; // read method name
|
ReadNextAtom; // read method name
|
||||||
{$IFDEF CTDEBUG}
|
|
||||||
writeln('TEventsCodeTool.RenamePublishedMethod D "',GetAtom,'"');
|
|
||||||
{$ENDIF}
|
|
||||||
Result:=SourceChangeCache.Replace(gtNone,gtNone,
|
Result:=SourceChangeCache.Replace(gtNone,gtNone,
|
||||||
CurPos.StartPos,CurPos.EndPos,NewMethodName);
|
CurPos.StartPos,CurPos.EndPos,NewMethodName);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEventsCodeTool.CreatePublishedMethod(const UpperClassName,
|
function TEventsCodeTool.CreatePublishedMethod(const UpperClassName,
|
||||||
AMethodName: string; TypeData: PTypeData;
|
AMethodName: string; ATypeInfo: PTypeInfo;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
var ClassNode: TCodeTreeNode;
|
var ClassNode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
BuildTree(false);
|
ActivateGlobalWriteLock;
|
||||||
if not EndOfSourceFound then exit;
|
try
|
||||||
ClassNode:=FindClassNodeInInterface(UpperClassName,true,false);
|
BuildTree(false);
|
||||||
Result:=CreatePublishedMethod(ClassNode,AMethodName,TypeData,
|
if not EndOfSourceFound then exit;
|
||||||
SourceChangeCache);
|
ClassNode:=FindClassNodeInInterface(UpperClassName,true,false);
|
||||||
|
Result:=CreatePublishedMethod(ClassNode,AMethodName,ATypeInfo,
|
||||||
|
SourceChangeCache);
|
||||||
|
finally
|
||||||
|
DeactivateGlobalWriteLock;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEventsCodeTool.CreatePublishedMethod(ClassNode: TCodeTreeNode;
|
function TEventsCodeTool.CreatePublishedMethod(ClassNode: TCodeTreeNode;
|
||||||
const AMethodName: string; TypeData: PTypeData;
|
const AMethodName: string; ATypeInfo: PTypeInfo;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
var PublishedNode: TCodeTreeNode;
|
var PublishedNode, ANode: TCodeTreeNode;
|
||||||
NewMethod: string;
|
NewMethod: string;
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
Result:=false;
|
||||||
if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) or (AMethodName='')
|
if (ClassNode=nil) or (ClassNode.Desc<>ctnClass) or (AMethodName='')
|
||||||
or (TypeData=nil) or (SourceChangeCache=nil) or (Scanner=nil) then exit;
|
or (ATypeInfo=nil) or (SourceChangeCache=nil) or (Scanner=nil) then exit;
|
||||||
SourceChangeCache.MainScanner:=Scanner;
|
ActivateGlobalWriteLock;
|
||||||
// add method to published section
|
try
|
||||||
BuildSubTreeForClass(ClassNode);
|
// convert TypeInfo to string
|
||||||
PublishedNode:=ClassNode.FirstChild;
|
NewMethod:=MethodTypeInfoToStr(ATypeInfo);
|
||||||
if PublishedNode=nil then exit;
|
|
||||||
if (PublishedNode.StartPos=PublishedNode.EndPos)
|
|
||||||
and (PublishedNode.NextBrother<>nil)
|
|
||||||
and (PublishedNode.NextBrother.Desc=ctnClassPublished) then
|
|
||||||
PublishedNode:=PublishedNode.NextBrother;
|
|
||||||
NewMethod:=MethodKindAsString[TypeData^.MethodKind]+' '+AMethodName+
|
|
||||||
MethodTypeDataToStr(TypeData,[phpWithVarModifiers,phpWithParameterNames]);
|
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
writeln('[TEventsCodeTool.CreatePublishedMethod] A NewMethod="',NewMethod,'"');
|
writeln('[TEventsCodeTool.CreatePublishedMethod] A NewMethod="',NewMethod,'"');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Result:=InsertNewMethodToClass(PublishedNode,AMethodName,NewMethod,
|
// add method to published section
|
||||||
SourceChangeCache);
|
SourceChangeCache.MainScanner:=Scanner;
|
||||||
|
BuildSubTreeForClass(ClassNode);
|
||||||
|
PublishedNode:=ClassNode.FirstChild;
|
||||||
|
if PublishedNode=nil then exit;
|
||||||
|
if (PublishedNode.StartPos=PublishedNode.EndPos)
|
||||||
|
and (PublishedNode.NextBrother<>nil)
|
||||||
|
and (PublishedNode.NextBrother.Desc=ctnClassPublished) then
|
||||||
|
PublishedNode:=PublishedNode.NextBrother;
|
||||||
|
// NewMethod:=MethodKindAsString[TypeData^.MethodKind]+' '+AMethodName+
|
||||||
|
// MethodTypeDataToStr(TypeData,[phpWithVarModifiers,phpWithParameterNames]);
|
||||||
|
|
||||||
|
// ToDo: check if parts already exists
|
||||||
|
|
||||||
|
Result:=InsertNewMethodToClass(PublishedNode,AMethodName,NewMethod,
|
||||||
|
SourceChangeCache);
|
||||||
|
finally
|
||||||
|
DeactivateGlobalWriteLock;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TEventsCodeTool.InsertNewMethodToClass(
|
function TEventsCodeTool.InsertNewMethodToClass(
|
||||||
@ -848,6 +888,66 @@ writeln('ParamCompatibility=',TypeCompatibilityNames[ParamCompatibility]);
|
|||||||
Result:=ifrProceedSearch;
|
Result:=ifrProceedSearch;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TEventsCodeTool.MethodTypeInfoToStr(ATypeInfo: PTypeInfo): string;
|
||||||
|
var TypeName: string;
|
||||||
|
Params: TFindDeclarationParams;
|
||||||
|
begin
|
||||||
|
ActivateGlobalWriteLock;
|
||||||
|
try
|
||||||
|
// find method type declaration
|
||||||
|
TypeName:=ATypeInfo^.Name;
|
||||||
|
Params:=TFindDeclarationParams.Create;
|
||||||
|
try
|
||||||
|
// find method type in used units
|
||||||
|
Params.ContextNode:=FindMainUsesSection;
|
||||||
|
if Params.ContextNode=nil then
|
||||||
|
Params.ContextNode:=Tree.Root;
|
||||||
|
Params.SetIdentifier(Self,@TypeName[1],nil);
|
||||||
|
Params.Flags:=[fdfExceptionOnNotFound,fdfSearchInParentNodes];
|
||||||
|
FindIdentifierInContext(Params);
|
||||||
|
// find proc node
|
||||||
|
if Params.NewNode.Desc<>ctnTypeDefinition then begin
|
||||||
|
Params.NewCodeTool.MoveCursorToNodeStart(Params.NewNode);
|
||||||
|
Params.NewCodeTool.RaiseException('method type definition not found');
|
||||||
|
end;
|
||||||
|
Params.NewNode:=FindTypeNodeOfDefinition(Params.NewNode);
|
||||||
|
if Params.NewNode.Desc<>ctnProcedure then begin
|
||||||
|
Params.NewCodeTool.MoveCursorToNodeStart(Params.NewNode);
|
||||||
|
Params.NewCodeTool.RaiseException('method type definition not found');
|
||||||
|
end;
|
||||||
|
Result:=Params.NewCodeTool.ExtractProcHead(Params.NewNode,
|
||||||
|
[phpWithStart, phpWithoutClassName, phpWithVarModifiers,
|
||||||
|
phpWithParameterNames, phpWithResultType, phpWithComments]);
|
||||||
|
finally
|
||||||
|
Params.Free;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
DeactivateGlobalWriteLock;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TEventsCodeTool.FindIdentifierNodeInClass(ClassNode: TCodeTreeNode;
|
||||||
|
Identifier: PChar): TCodeTreeNode;
|
||||||
|
var
|
||||||
|
VisibilityNode: TCodeTreeNode;
|
||||||
|
begin
|
||||||
|
BuildSubTreeForClass(ClassNode);
|
||||||
|
VisibilityNode:=ClassNode.FirstChild;
|
||||||
|
while (VisibilityNode<>nil) do begin
|
||||||
|
Result:=VisibilityNode.FirstChild;
|
||||||
|
while Result<>nil do begin
|
||||||
|
if CompareSrcIdentifiers(Result.FirstChild.StartPos,Identifier) then
|
||||||
|
begin
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
Result:=Result.NextBrother;
|
||||||
|
end;
|
||||||
|
VisibilityNode:=VisibilityNode.NextBrother;
|
||||||
|
end;
|
||||||
|
Result:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -359,6 +359,11 @@ const
|
|||||||
fdfExceptionOnNotFound]+fdfAllClassVisibilities;
|
fdfExceptionOnNotFound]+fdfAllClassVisibilities;
|
||||||
|
|
||||||
function ExprTypeToString(ExprType: TExpressionType): string;
|
function ExprTypeToString(ExprType: TExpressionType): string;
|
||||||
|
function CreateFindContext(NewTool: TFindDeclarationTool;
|
||||||
|
NewNode: TCodeTreeNode): TFindContext;
|
||||||
|
function CreateFindContext(Params: TFindDeclarationParams): TFindContext;
|
||||||
|
function CreateFindContext(BaseTypeCache: TBaseTypeCache): TFindContext;
|
||||||
|
function FindContextAreEqual(Context1, Context2: TFindContext): boolean;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -827,7 +832,9 @@ function TFindDeclarationTool.FindIdentifierInContext(
|
|||||||
Result:
|
Result:
|
||||||
true, if NewPos+NewTopLine valid
|
true, if NewPos+NewTopLine valid
|
||||||
}
|
}
|
||||||
var LastContextNode, StartContextNode, ContextNode: TCodeTreeNode;
|
var
|
||||||
|
LastContextNode, StartContextNode, FirstSearchedNode,
|
||||||
|
ContextNode: TCodeTreeNode;
|
||||||
IsForward: boolean;
|
IsForward: boolean;
|
||||||
IdentifierFoundResult: TIdentifierFoundResult;
|
IdentifierFoundResult: TIdentifierFoundResult;
|
||||||
LastNodeCache: TCodeTreeNodeCache;
|
LastNodeCache: TCodeTreeNodeCache;
|
||||||
@ -871,6 +878,7 @@ var LastContextNode, StartContextNode, ContextNode: TCodeTreeNode;
|
|||||||
begin
|
begin
|
||||||
ContextNode:=Params.ContextNode;
|
ContextNode:=Params.ContextNode;
|
||||||
StartContextNode:=ContextNode;
|
StartContextNode:=ContextNode;
|
||||||
|
FirstSearchedNode:=nil;
|
||||||
Result:=false;
|
Result:=false;
|
||||||
if ContextNode=nil then begin
|
if ContextNode=nil then begin
|
||||||
RaiseException('[TFindDeclarationTool.FindIdentifierInContext] '
|
RaiseException('[TFindDeclarationTool.FindIdentifierInContext] '
|
||||||
@ -891,15 +899,16 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] A Ident=',
|
|||||||
if (ContextNode.Desc=ctnClass) then
|
if (ContextNode.Desc=ctnClass) then
|
||||||
writeln(' ContextNode.LastChild=',ContextNode.LastChild<>nil);
|
writeln(' ContextNode.LastChild=',ContextNode.LastChild<>nil);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
// search in cache
|
|
||||||
if FindInNodeCache then begin
|
|
||||||
Result:=(Params.NewNode<>nil);
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// search identifier in current context
|
// search identifier in current context
|
||||||
LastContextNode:=ContextNode;
|
LastContextNode:=ContextNode;
|
||||||
if not (fdfIgnoreCurContextNode in Params.Flags) then begin
|
if not (fdfIgnoreCurContextNode in Params.Flags) then begin
|
||||||
|
// search in cache
|
||||||
|
if FindInNodeCache then begin
|
||||||
|
Result:=(Params.NewNode<>nil);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if FirstSearchedNode=nil then FirstSearchedNode:=ContextNode;
|
||||||
|
|
||||||
case ContextNode.Desc of
|
case ContextNode.Desc of
|
||||||
|
|
||||||
ctnTypeSection, ctnVarSection, ctnConstSection, ctnResStrSection,
|
ctnTypeSection, ctnVarSection, ctnConstSection, ctnResStrSection,
|
||||||
@ -1159,16 +1168,19 @@ writeln('[TFindDeclarationTool.FindIdentifierInContext] Searching in Parent Con
|
|||||||
until ContextNode=nil;
|
until ContextNode=nil;
|
||||||
|
|
||||||
finally
|
finally
|
||||||
if Result and (not (fdfDoNotCache in Params.NewFlags)) then begin
|
if Result and (not (fdfDoNotCache in Params.NewFlags))
|
||||||
|
and (FirstSearchedNode<>nil) then begin
|
||||||
// add result to caches
|
// add result to caches
|
||||||
AddResultToNodeCaches(Params.Identifier,StartContextNode,ContextNode,
|
AddResultToNodeCaches(Params.Identifier,FirstSearchedNode,ContextNode,
|
||||||
fdfSearchForward in Params.Flags,Params);
|
fdfSearchForward in Params.Flags,Params);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
// if we are here, the identifier was not found
|
// if we are here, the identifier was not found
|
||||||
// add result to cache
|
if FirstSearchedNode<>nil then begin
|
||||||
AddResultToNodeCaches(Params.Identifier,StartContextNode,ContextNode,
|
// add result to cache
|
||||||
fdfSearchForward in Params.Flags,nil);
|
AddResultToNodeCaches(Params.Identifier,FirstSearchedNode,ContextNode,
|
||||||
|
fdfSearchForward in Params.Flags,nil);
|
||||||
|
end;
|
||||||
|
|
||||||
if fdfExceptionOnNotFound in Params.Flags then begin
|
if fdfExceptionOnNotFound in Params.Flags then begin
|
||||||
if Params.IdentifierTool.IsPCharInSrc(Params.Identifier) then
|
if Params.IdentifierTool.IsPCharInSrc(Params.Identifier) then
|
||||||
@ -1700,12 +1712,7 @@ writeln('[TFindDeclarationTool.FindBaseTypeOfNode] LOOP Result=',Result.Node.Des
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
if (Result.Node.Desc in AllIdentifierDefinitions) then begin
|
if (Result.Node.Desc in AllIdentifierDefinitions) then begin
|
||||||
// instead of variable/const/type definition, return the type
|
// instead of variable/const/type definition, return the type
|
||||||
DummyNode:=FindTypeNodeOfDefinition(Result.Node);
|
Result.Node:=FindTypeNodeOfDefinition(Result.Node);
|
||||||
if (DummyNode<>nil) or (Result.Node.Parent.Desc<>ctnParameterList) then
|
|
||||||
Result.Node:=DummyNode
|
|
||||||
else
|
|
||||||
// in parameter lists are definitions without type allowed
|
|
||||||
exit;
|
|
||||||
end else
|
end else
|
||||||
if (Result.Node.Desc=ctnClass)
|
if (Result.Node.Desc=ctnClass)
|
||||||
and ((Result.Node.SubDesc and ctnsForwardDeclaration)>0) then
|
and ((Result.Node.SubDesc and ctnsForwardDeclaration)>0) then
|
||||||
@ -3776,9 +3783,9 @@ begin
|
|||||||
{$IFDEF ShowNodeCache}
|
{$IFDEF ShowNodeCache}
|
||||||
write('TFindDeclarationTool.AddResultToNodeCaches ',
|
write('TFindDeclarationTool.AddResultToNodeCaches ',
|
||||||
' Ident=',GetIdentifier(Identifier),
|
' Ident=',GetIdentifier(Identifier),
|
||||||
' StartNode=',StartNode.DescAsString,'="',copy(Src,StartNode.StartPos,12),'"');
|
' StartNode=',StartNode.DescAsString,'="',copy(Src,StartNode.StartPos-10,10),'|',copy(Src,StartNode.StartPos,15),'"');
|
||||||
if EndNode<>nil then
|
if EndNode<>nil then
|
||||||
write(' EndNode=',EndNode.DescAsString,'="',copy(Src,EndNode.StartPos,12),'"')
|
write(' EndNode=',EndNode.DescAsString,'="',copy(Src,EndNode.StartPos,25),'"')
|
||||||
else
|
else
|
||||||
write(' EndNode=nil');
|
write(' EndNode=nil');
|
||||||
write(' SearchedForward=',SearchedForward);
|
write(' SearchedForward=',SearchedForward);
|
||||||
@ -3814,6 +3821,9 @@ end;
|
|||||||
else
|
else
|
||||||
CleanEndPos:=SrcLen+1;
|
CleanEndPos:=SrcLen+1;
|
||||||
end;
|
end;
|
||||||
|
{$IFDEF ShowNodeCache}
|
||||||
|
writeln(' CleanStartPos=',CleanStartPos,' CleanEndPos=',CleanEndPos);
|
||||||
|
{$ENDIF}
|
||||||
while (Node<>nil) do begin
|
while (Node<>nil) do begin
|
||||||
if (Node.Desc in AllNodeCacheDescs) then begin
|
if (Node.Desc in AllNodeCacheDescs) then begin
|
||||||
if (Node.Cache=nil) then
|
if (Node.Cache=nil) then
|
||||||
@ -3860,7 +3870,9 @@ write('[TFindDeclarationTool.CreateBaseTypeCaches] ',
|
|||||||
writeln(' Self=',MainFilename);
|
writeln(' Self=',MainFilename);
|
||||||
if Result.Node<>nil then
|
if Result.Node<>nil then
|
||||||
write(' Result=',Result.Node.DescAsString,
|
write(' Result=',Result.Node.DescAsString,
|
||||||
' "',copy(Src,Result.Node.StartPos,10),'" ',Result.Tool.MainFilename)
|
' Start=',Result.Node.StartPos,
|
||||||
|
' End=',Result.Node.EndPos,
|
||||||
|
' "',copy(Src,Result.Node.StartPos,15),'" ',Result.Tool.MainFilename)
|
||||||
else
|
else
|
||||||
write(' Result=nil');
|
write(' Result=nil');
|
||||||
writeln('');
|
writeln('');
|
||||||
@ -3870,7 +3882,7 @@ writeln('');
|
|||||||
if (Node.Cache=nil)
|
if (Node.Cache=nil)
|
||||||
and ((Result.Tool<>Self) or (Result.Node<>Node)) then begin
|
and ((Result.Tool<>Self) or (Result.Node<>Node)) then begin
|
||||||
{$IFDEF ShowBaseTypeCache}
|
{$IFDEF ShowBaseTypeCache}
|
||||||
writeln(' i=',i,' Node=',Node.DescAsString,' "',copy(Src,Node.StartPos,10),'"');
|
writeln(' i=',i,' Node=',Node.DescAsString,' "',copy(Src,Node.StartPos,15),'"');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
BaseTypeCache:=CreateNewBaseTypeCache(Node);
|
BaseTypeCache:=CreateNewBaseTypeCache(Node);
|
||||||
if BaseTypeCache<>nil then begin
|
if BaseTypeCache<>nil then begin
|
||||||
|
@ -72,12 +72,25 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TProcHeadAttribute = (phpWithStart, phpAddClassname, phpWithoutClassName,
|
TProcHeadAttribute = (
|
||||||
phpWithoutName, phpWithVarModifiers, phpWithParameterNames,
|
phpWithStart, // proc keyword e.g. 'function', 'class procedure'
|
||||||
phpWithDefaultValues, phpWithResultType, phpWithComments, phpInUpperCase,
|
phpAddClassname, // extract/add 'ClassName.'
|
||||||
phpWithoutBrackets, phpIgnoreForwards, phpIgnoreProcsWithBody,
|
phpWithoutClassName, // skip classname
|
||||||
phpOnlyWithClassname, phpFindCleanPosition, phpWithoutParamList,
|
phpWithoutName, // skip function name
|
||||||
phpCreateNodes);
|
phpWithVarModifiers, // extract 'var', 'out', 'const'
|
||||||
|
phpWithParameterNames, // extract parameter names
|
||||||
|
phpWithDefaultValues, // extract default values
|
||||||
|
phpWithResultType, // extract colon + result type
|
||||||
|
phpWithComments, // extract comments
|
||||||
|
phpInUpperCase, // turn to uppercase
|
||||||
|
phpWithoutBrackets, // skip start- and end-bracket of parameter list
|
||||||
|
phpIgnoreForwards, // skip forward procs
|
||||||
|
phpIgnoreProcsWithBody,// skip procs with begin..end
|
||||||
|
phpOnlyWithClassname, // skip procs without the right classname
|
||||||
|
phpFindCleanPosition, // read til ExtractSearchPos
|
||||||
|
phpWithoutParamList, // skip param list
|
||||||
|
phpCreateNodes // create nodes during reading
|
||||||
|
);
|
||||||
TProcHeadAttributes = set of TProcHeadAttribute;
|
TProcHeadAttributes = set of TProcHeadAttribute;
|
||||||
|
|
||||||
TProcHeadExtractPos = (phepNone, phepStart, phepName, phepParamList);
|
TProcHeadExtractPos = (phepNone, phepStart, phepName, phepParamList);
|
||||||
@ -1000,6 +1013,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
end else begin
|
||||||
|
// no type -> variant
|
||||||
|
if (phpCreateNodes in Attr) then begin
|
||||||
|
CreateChildNode;
|
||||||
|
CurNode.Desc:=ctnVariantType;
|
||||||
|
CurNode.EndPos:=CurNode.StartPos;
|
||||||
|
EndChildNode;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
if (phpCreateNodes in Attr) then begin
|
if (phpCreateNodes in Attr) then begin
|
||||||
CurNode.EndPos:=CurPos.EndPos;
|
CurNode.EndPos:=CurPos.EndPos;
|
||||||
|
56
ide/main.pp
56
ide/main.pp
@ -271,9 +271,14 @@ type
|
|||||||
|
|
||||||
// ObjectInspector + PropertyEditorHook events
|
// ObjectInspector + PropertyEditorHook events
|
||||||
procedure OIOnAddAvailableComponent(AComponent:TComponent;
|
procedure OIOnAddAvailableComponent(AComponent:TComponent;
|
||||||
var Allowed:boolean);
|
var Allowed:boolean);
|
||||||
procedure OIOnSelectComponent(AComponent:TComponent);
|
procedure OIOnSelectComponent(AComponent:TComponent);
|
||||||
procedure OnPropHookGetMethods(TypeData:PTypeData; Proc:TGetStringProc);
|
procedure OnPropHookGetMethods(TypeData:PTypeData; Proc:TGetStringProc);
|
||||||
|
function OnPropHookMethodExists(const AMethodName:ShortString;
|
||||||
|
TypeData: PTypeData;
|
||||||
|
var MethodIsCompatible,MethodIsPublished,IdentIsMethod: boolean):boolean;
|
||||||
|
function OnPropHookCreateMethod(const AMethodName:ShortString;
|
||||||
|
ATypeInfo:PTypeInfo): TMethod;
|
||||||
|
|
||||||
// Environment options dialog events
|
// Environment options dialog events
|
||||||
procedure OnLoadEnvironmentSettings(Sender: TObject;
|
procedure OnLoadEnvironmentSettings(Sender: TObject;
|
||||||
@ -701,6 +706,7 @@ begin
|
|||||||
PropertyEditorHook1:=TPropertyEditorHook.Create;
|
PropertyEditorHook1:=TPropertyEditorHook.Create;
|
||||||
{$IFDEF TestEvents}
|
{$IFDEF TestEvents}
|
||||||
PropertyEditorHook1.OnGetMethods:=@OnPropHookGetMethods;
|
PropertyEditorHook1.OnGetMethods:=@OnPropHookGetMethods;
|
||||||
|
PropertyEditorHook1.OnMethodExists:=@OnPropHookMethodExists;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
ObjectInspector1.PropertyEditorHook:=PropertyEditorHook1;
|
ObjectInspector1.PropertyEditorHook:=PropertyEditorHook1;
|
||||||
ObjectInspector1.Show;
|
ObjectInspector1.Show;
|
||||||
@ -904,7 +910,7 @@ begin
|
|||||||
writeln('');
|
writeln('');
|
||||||
writeln('[TMainIDE.OnPropHookGetMethods] ************');
|
writeln('[TMainIDE.OnPropHookGetMethods] ************');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
if not CodeToolBoss.GetCompatibleMethods(ActiveUnitInfo.Source,
|
if not CodeToolBoss.GetCompatiblePublishedMethods(ActiveUnitInfo.Source,
|
||||||
ActiveUnitInfo.Form.ClassName,TypeData,Proc) then
|
ActiveUnitInfo.Form.ClassName,TypeData,Proc) then
|
||||||
begin
|
begin
|
||||||
DoJumpToCodeToolBossError;
|
DoJumpToCodeToolBossError;
|
||||||
@ -5826,6 +5832,49 @@ begin
|
|||||||
ActiveUnitInfo:=nil;
|
ActiveUnitInfo:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TMainIDE.OnPropHookMethodExists(const AMethodName: ShortString;
|
||||||
|
TypeData: PTypeData;
|
||||||
|
var MethodIsCompatible,MethodIsPublished,IdentIsMethod: boolean): boolean;
|
||||||
|
var ActiveSrcEdit: TSourceEditor;
|
||||||
|
ActiveUnitInfo: TUnitInfo;
|
||||||
|
begin
|
||||||
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,true) then exit;
|
||||||
|
{$IFDEF IDE_DEBUG}
|
||||||
|
writeln('');
|
||||||
|
writeln('[TMainIDE.OnPropHookMethodExists] ************');
|
||||||
|
{$ENDIF}
|
||||||
|
Result:=CodeToolBoss.PublishedMethodExists(ActiveUnitInfo.Source,
|
||||||
|
ActiveUnitInfo.Form.ClassName,AMethodName,TypeData,
|
||||||
|
MethodIsCompatible,MethodIsPublished,IdentIsMethod);
|
||||||
|
if CodeToolBoss.ErrorMessage<>'' then begin
|
||||||
|
DoJumpToCodeToolBossError;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TMainIDE.OnPropHookCreateMethod(const AMethodName: ShortString;
|
||||||
|
ATypeInfo: PTypeInfo): TMethod;
|
||||||
|
var ActiveSrcEdit: TSourceEditor;
|
||||||
|
ActiveUnitInfo: TUnitInfo;
|
||||||
|
begin
|
||||||
|
Result.Code:=nil;
|
||||||
|
Result.Data:=nil;
|
||||||
|
if not BeginCodeTool(ActiveSrcEdit,ActiveUnitInfo,true) then exit;
|
||||||
|
{$IFDEF IDE_DEBUG}
|
||||||
|
writeln('');
|
||||||
|
writeln('[TMainIDE.OnPropHookCreateMethod] ************');
|
||||||
|
{$ENDIF}
|
||||||
|
// create published method
|
||||||
|
if CodeToolBoss.CreatePublishedMethod(ActiveUnitInfo.Source,
|
||||||
|
ActiveUnitInfo.Form.ClassName,AMethodName,ATypeInfo) then
|
||||||
|
begin
|
||||||
|
|
||||||
|
// ToDo: create published method in form
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
DoJumpToCodeToolBossError;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -5840,6 +5889,9 @@ end.
|
|||||||
|
|
||||||
{ =============================================================================
|
{ =============================================================================
|
||||||
$Log$
|
$Log$
|
||||||
|
Revision 1.221 2002/02/10 20:44:00 lazarus
|
||||||
|
MG: fixed a node cache range bug
|
||||||
|
|
||||||
Revision 1.220 2002/02/09 22:24:50 lazarus
|
Revision 1.220 2002/02/09 22:24:50 lazarus
|
||||||
MG: get compatible published methods now works
|
MG: get compatible published methods now works
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user