codetools: identifier completion: show generic parameters

git-svn-id: trunk@50341 -
This commit is contained in:
mattias 2015-11-16 21:28:38 +00:00
parent a8546cf427
commit 07d6956baa
5 changed files with 75 additions and 30 deletions

View File

@ -138,12 +138,12 @@ const
ctnSpecialize = 88; ctnSpecialize = 88;
ctnSpecializeType = 89; ctnSpecializeType = 89;
ctnSpecializeParams = 90; 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 ctnGenericName = 92; // parent = ctnGenericType
ctnGenericParams = 93; // parent = ctnGenericType, children = ctnGenericParameter ctnGenericParams = 93; // parent = ctnGenericType, children = ctnGenericParameter
ctnGenericParameter = 94; // can has a child ctnGenericConstraint ctnGenericParameter = 94; // can has a child ctnGenericConstraint
ctnGenericConstraint = 95; // parent = ctnGenericParameter ctnGenericConstraint = 95; // parent = ctnGenericParameter
ctnReferenceTo = 96; // 1. child = ctnProcedure ctnReferenceTo = 96; // 1st child = ctnProcedure
ctnConstant = 97; ctnConstant = 97;
ctnHintModifier = 98; // deprecated, platform, unimplemented, library, experimental ctnHintModifier = 98; // deprecated, platform, unimplemented, library, experimental

View File

@ -3739,22 +3739,19 @@ var
end; end;
end; end;
function SearchInGenericParams(GenericNode: TCodeTreeNode): boolean; function SearchInGenericParams(GenParamsNode: TCodeTreeNode): boolean;
var var
Node: TCodeTreeNode; Node: TCodeTreeNode;
begin begin
Result:=false; Result:=false;
Node:=GenericNode.FirstChild; if (GenParamsNode=nil) or (GenParamsNode.Desc<>ctnGenericParams) then exit;
if Node=nil then exit; Node:=GenParamsNode.FirstChild;
Node:=Node.NextBrother;
if (Node=nil) or (Node.Desc<>ctnGenericParams) then exit;
Node:=Node.FirstChild;
while Node<>nil do begin while Node<>nil do begin
if (fdfCollect in Flags) if (fdfCollect in Flags)
or CompareSrcIdentifiers(Node.StartPos,Params.Identifier) or CompareSrcIdentifiers(Node.StartPos,Params.Identifier)
then begin then begin
{$IFDEF ShowTriedIdentifiers} {$IFDEF ShowTriedIdentifiers}
DebugLn(' SearchInGenericParams Identifier found="',GetIdentifier(Params.Identifier),'"'); DebugLn(' SearchInGenericParams Identifier found="',GetIdentifier(@Src[Node.StartPos]),'" at '+CleanPosToStr(Node.StartPos));
{$ENDIF} {$ENDIF}
// identifier found // identifier found
Params.SetResult(Self,Node); Params.SetResult(Self,Node);
@ -3806,6 +3803,44 @@ var
end; end;
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; function SearchInTypeOfVarConst: boolean;
// returns: true if ok to exit // returns: true if ok to exit
// false if search should continue // false if search should continue
@ -4056,10 +4091,13 @@ var
{$ENDIF} {$ENDIF}
LastSearchedNode:=ContextNode; LastSearchedNode:=ContextNode;
if (ContextNode.Parent<>nil) and (ContextNode.Parent.Desc=ctnGenericType) if (ContextNode.Desc in AllClasses) then begin
// after searching in a class definition ...
if (ContextNode.PriorBrother<>nil) and (ContextNode.PriorBrother.Desc=ctnGenericParams)
then begin then begin
// after search in the generic, search in the generic parameter names // before searching in the ancestors, search in the generic parameters
if SearchInGenericParams(ContextNode.Parent) then begin if SearchInGenericParams(ContextNode.PriorBrother) then begin
FindIdentifierInContext:=true; FindIdentifierInContext:=true;
{$IFDEF ShowCollect} {$IFDEF ShowCollect}
if fdfCollect in Flags then if fdfCollect in Flags then
@ -4069,7 +4107,6 @@ var
end; end;
end; end;
if (ContextNode.Desc in AllClasses) then begin
//allow ctnRecordType and ctnTypeTypeBeforeHelper: they can have helpers! //allow ctnRecordType and ctnTypeTypeBeforeHelper: they can have helpers!
if (fdfSearchInAncestors in Flags) then begin if (fdfSearchInAncestors in Flags) then begin
// after searching in a class definition, search in its ancestors // after searching in a class definition, search in its ancestors
@ -4354,9 +4391,13 @@ begin
MoveContextNodeToChildren; MoveContextNodeToChildren;
ctnTypeDefinition, ctnVarDefinition, ctnConstDefinition, ctnTypeDefinition, ctnVarDefinition, ctnConstDefinition,
ctnGenericType, ctnGlobalProperty: ctnGlobalProperty:
if SearchInTypeVarConstGlobPropDefinition then exit; if SearchInTypeVarConstGlobPropDefinition then exit;
ctnGenericType:
if SearchInGenericType then exit;
// ctnGenericParams: skip here, it was searched before searching the ancestors
ctnIdentifier: ctnIdentifier:
if (ContextNode.Parent.Desc in [ctnConstDefinition,ctnVarDefinition]) if (ContextNode.Parent.Desc in [ctnConstDefinition,ctnVarDefinition])
and (ContextNode=ContextNode.Parent.LastChild) and (ContextNode=ContextNode.Parent.LastChild)

View File

@ -1216,6 +1216,9 @@ begin
end; end;
end; end;
ctnGenericParameter:
Ident:=@FoundContext.Tool.Src[FoundContext.Node.StartPos];
ctnVarDefinition,ctnConstDefinition,ctnEnumIdentifier,ctnLabel,ctnGlobalProperty: ctnVarDefinition,ctnConstDefinition,ctnEnumIdentifier,ctnLabel,ctnGlobalProperty:
Ident:=@FoundContext.Tool.Src[FoundContext.Node.StartPos]; Ident:=@FoundContext.Tool.Src[FoundContext.Node.StartPos];

View File

@ -11,16 +11,16 @@ uses
Classes, SysUtils; Classes, SysUtils;
type type
generic TGenBaseAction<T> = class generic TGenBaseAction<GenParam1> = class
BaseName: T{declaration:fdt_generics.TGenBaseAction.T}; BaseName: GenParam1{declaration:fdt_generics.TGenBaseAction.GenParam1};
end; end;
generic TGenCustomAction<T> = class(specialize TGenBaseAction{declaration:fdt_generics.TGenBaseAction}<T>) generic TGenCustomAction<GenParam2> = class(specialize TGenBaseAction{declaration:fdt_generics.TGenBaseAction}<GenParam2>)
CustomName: T; CustomName: GenParam2;
end; end;
generic TGenAction<T> = class(specialize TGenCustomAction{declaration:fdt_generics.TGenCustomAction}<T>) generic TGenAction<GenParam3> = class(specialize TGenCustomAction{declaration:fdt_generics.TGenCustomAction}<GenParam3>)
ActionName: T; ActionName: GenParam3;
end; end;
implementation implementation

View File

@ -90,7 +90,7 @@ procedure TTestFindDeclaration.FindDeclarations(Filename: string);
end; end;
Node:=Node.Parent; Node:=Node.Parent;
end; end;
debugln(['NodeAsPath ',Result]); //debugln(['NodeAsPath ',Result]);
end; end;
var var
@ -191,6 +191,7 @@ begin
i:=CodeToolBoss.IdentifierList.GetFilteredCount-1; i:=CodeToolBoss.IdentifierList.GetFilteredCount-1;
while i>=0 do begin while i>=0 do begin
IdentItem:=CodeToolBoss.IdentifierList.FilteredItems[i]; IdentItem:=CodeToolBoss.IdentifierList.FilteredItems[i];
//debugln(['TTestFindDeclaration.FindDeclarations ',IdentItem.Identifier]);
l:=length(IdentItem.Identifier); l:=length(IdentItem.Identifier);
if ((l=length(ExpectedPath)) or (ExpectedPath[length(ExpectedPath)-l]='.')) if ((l=length(ExpectedPath)) or (ExpectedPath[length(ExpectedPath)-l]='.'))
and (CompareText(IdentItem.Identifier,RightStr(ExpectedPath,l))=0) and (CompareText(IdentItem.Identifier,RightStr(ExpectedPath,l))=0)