mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-02 22:27:30 +01:00
codetools: identifier completion: show generic parameters
git-svn-id: trunk@50341 -
This commit is contained in:
parent
a8546cf427
commit
07d6956baa
@ -138,12 +138,12 @@ const
|
||||
ctnSpecialize = 88;
|
||||
ctnSpecializeType = 89;
|
||||
ctnSpecializeParams = 90;
|
||||
ctnGenericType = 91;// 1. child = ctnGenericName, 2. child = ctnGenericParams, 3. child = type
|
||||
ctnGenericType = 91;// 1st child = ctnGenericName, 2nd child = ctnGenericParams, 3th child = type
|
||||
ctnGenericName = 92; // parent = ctnGenericType
|
||||
ctnGenericParams = 93; // parent = ctnGenericType, children = ctnGenericParameter
|
||||
ctnGenericParameter = 94; // can has a child ctnGenericConstraint
|
||||
ctnGenericConstraint = 95; // parent = ctnGenericParameter
|
||||
ctnReferenceTo = 96; // 1. child = ctnProcedure
|
||||
ctnReferenceTo = 96; // 1st child = ctnProcedure
|
||||
ctnConstant = 97;
|
||||
ctnHintModifier = 98; // deprecated, platform, unimplemented, library, experimental
|
||||
|
||||
|
||||
@ -3739,22 +3739,19 @@ var
|
||||
end;
|
||||
end;
|
||||
|
||||
function SearchInGenericParams(GenericNode: TCodeTreeNode): boolean;
|
||||
function SearchInGenericParams(GenParamsNode: TCodeTreeNode): boolean;
|
||||
var
|
||||
Node: TCodeTreeNode;
|
||||
begin
|
||||
Result:=false;
|
||||
Node:=GenericNode.FirstChild;
|
||||
if Node=nil then exit;
|
||||
Node:=Node.NextBrother;
|
||||
if (Node=nil) or (Node.Desc<>ctnGenericParams) then exit;
|
||||
Node:=Node.FirstChild;
|
||||
if (GenParamsNode=nil) or (GenParamsNode.Desc<>ctnGenericParams) then exit;
|
||||
Node:=GenParamsNode.FirstChild;
|
||||
while Node<>nil do begin
|
||||
if (fdfCollect in Flags)
|
||||
or CompareSrcIdentifiers(Node.StartPos,Params.Identifier)
|
||||
then begin
|
||||
{$IFDEF ShowTriedIdentifiers}
|
||||
DebugLn(' SearchInGenericParams Identifier found="',GetIdentifier(Params.Identifier),'"');
|
||||
DebugLn(' SearchInGenericParams Identifier found="',GetIdentifier(@Src[Node.StartPos]),'" at '+CleanPosToStr(Node.StartPos));
|
||||
{$ENDIF}
|
||||
// identifier found
|
||||
Params.SetResult(Self,Node);
|
||||
@ -3806,6 +3803,44 @@ var
|
||||
end;
|
||||
end;
|
||||
|
||||
function SearchInGenericType: boolean;
|
||||
// returns: true if ok to exit
|
||||
// false if search should continue
|
||||
var
|
||||
NameNode: TCodeTreeNode;
|
||||
begin
|
||||
Result:=false;
|
||||
NameNode:=ContextNode.FirstChild;
|
||||
if NameNode=nil then exit;
|
||||
|
||||
// try type name
|
||||
if (fdfCollect in Flags)
|
||||
or CompareSrcIdentifiers(NameNode.StartPos,Params.Identifier)
|
||||
then begin
|
||||
{$IFDEF ShowTriedIdentifiers}
|
||||
DebugLn(' Definition Identifier found="',GetIdentifier(Params.Identifier),'"');
|
||||
{$ENDIF}
|
||||
// identifier found
|
||||
Params.SetResult(Self,ContextNode);
|
||||
Result:=CheckResult(true,true);
|
||||
if not (fdfCollect in Flags) then begin
|
||||
if (fdfSkipClassForward in Flags)
|
||||
and (ContextNode.LastChild.Desc in AllClasses)
|
||||
and ((ctnsForwardDeclaration and ContextNode.LastChild.SubDesc)<>0)
|
||||
then begin
|
||||
FindNonForwardClass(Params);
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
// search for enums
|
||||
Params.ContextNode:=ContextNode;
|
||||
if FindEnumInContext(Params) then begin
|
||||
Result:=CheckResult(true,false);
|
||||
end;
|
||||
end;
|
||||
|
||||
function SearchInTypeOfVarConst: boolean;
|
||||
// returns: true if ok to exit
|
||||
// false if search should continue
|
||||
@ -4056,20 +4091,22 @@ var
|
||||
{$ENDIF}
|
||||
LastSearchedNode:=ContextNode;
|
||||
|
||||
if (ContextNode.Parent<>nil) and (ContextNode.Parent.Desc=ctnGenericType)
|
||||
then begin
|
||||
// after search in the generic, search in the generic parameter names
|
||||
if SearchInGenericParams(ContextNode.Parent) then begin
|
||||
FindIdentifierInContext:=true;
|
||||
{$IFDEF ShowCollect}
|
||||
if fdfCollect in Flags then
|
||||
raise Exception.Create('fdfCollect must never return true');
|
||||
{$ENDIF}
|
||||
exit(AbortNoCacheResult);
|
||||
end;
|
||||
end;
|
||||
|
||||
if (ContextNode.Desc in AllClasses) then begin
|
||||
// after searching in a class definition ...
|
||||
|
||||
if (ContextNode.PriorBrother<>nil) and (ContextNode.PriorBrother.Desc=ctnGenericParams)
|
||||
then begin
|
||||
// before searching in the ancestors, search in the generic parameters
|
||||
if SearchInGenericParams(ContextNode.PriorBrother) then begin
|
||||
FindIdentifierInContext:=true;
|
||||
{$IFDEF ShowCollect}
|
||||
if fdfCollect in Flags then
|
||||
raise Exception.Create('fdfCollect must never return true');
|
||||
{$ENDIF}
|
||||
exit(AbortNoCacheResult);
|
||||
end;
|
||||
end;
|
||||
|
||||
//allow ctnRecordType and ctnTypeTypeBeforeHelper: they can have helpers!
|
||||
if (fdfSearchInAncestors in Flags) then begin
|
||||
// after searching in a class definition, search in its ancestors
|
||||
@ -4354,9 +4391,13 @@ begin
|
||||
MoveContextNodeToChildren;
|
||||
|
||||
ctnTypeDefinition, ctnVarDefinition, ctnConstDefinition,
|
||||
ctnGenericType, ctnGlobalProperty:
|
||||
ctnGlobalProperty:
|
||||
if SearchInTypeVarConstGlobPropDefinition then exit;
|
||||
|
||||
ctnGenericType:
|
||||
if SearchInGenericType then exit;
|
||||
// ctnGenericParams: skip here, it was searched before searching the ancestors
|
||||
|
||||
ctnIdentifier:
|
||||
if (ContextNode.Parent.Desc in [ctnConstDefinition,ctnVarDefinition])
|
||||
and (ContextNode=ContextNode.Parent.LastChild)
|
||||
|
||||
@ -1215,6 +1215,9 @@ begin
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
ctnGenericParameter:
|
||||
Ident:=@FoundContext.Tool.Src[FoundContext.Node.StartPos];
|
||||
|
||||
ctnVarDefinition,ctnConstDefinition,ctnEnumIdentifier,ctnLabel,ctnGlobalProperty:
|
||||
Ident:=@FoundContext.Tool.Src[FoundContext.Node.StartPos];
|
||||
|
||||
@ -11,16 +11,16 @@ uses
|
||||
Classes, SysUtils;
|
||||
|
||||
type
|
||||
generic TGenBaseAction<T> = class
|
||||
BaseName: T{declaration:fdt_generics.TGenBaseAction.T};
|
||||
generic TGenBaseAction<GenParam1> = class
|
||||
BaseName: GenParam1{declaration:fdt_generics.TGenBaseAction.GenParam1};
|
||||
end;
|
||||
|
||||
generic TGenCustomAction<T> = class(specialize TGenBaseAction{declaration:fdt_generics.TGenBaseAction}<T>)
|
||||
CustomName: T;
|
||||
generic TGenCustomAction<GenParam2> = class(specialize TGenBaseAction{declaration:fdt_generics.TGenBaseAction}<GenParam2>)
|
||||
CustomName: GenParam2;
|
||||
end;
|
||||
|
||||
generic TGenAction<T> = class(specialize TGenCustomAction{declaration:fdt_generics.TGenCustomAction}<T>)
|
||||
ActionName: T;
|
||||
generic TGenAction<GenParam3> = class(specialize TGenCustomAction{declaration:fdt_generics.TGenCustomAction}<GenParam3>)
|
||||
ActionName: GenParam3;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
@ -90,7 +90,7 @@ procedure TTestFindDeclaration.FindDeclarations(Filename: string);
|
||||
end;
|
||||
Node:=Node.Parent;
|
||||
end;
|
||||
debugln(['NodeAsPath ',Result]);
|
||||
//debugln(['NodeAsPath ',Result]);
|
||||
end;
|
||||
|
||||
var
|
||||
@ -191,6 +191,7 @@ begin
|
||||
i:=CodeToolBoss.IdentifierList.GetFilteredCount-1;
|
||||
while i>=0 do begin
|
||||
IdentItem:=CodeToolBoss.IdentifierList.FilteredItems[i];
|
||||
//debugln(['TTestFindDeclaration.FindDeclarations ',IdentItem.Identifier]);
|
||||
l:=length(IdentItem.Identifier);
|
||||
if ((l=length(ExpectedPath)) or (ExpectedPath[length(ExpectedPath)-l]='.'))
|
||||
and (CompareText(IdentItem.Identifier,RightStr(ExpectedPath,l))=0)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user