codetools: FindCodeContext of attribute params

git-svn-id: trunk@56513 -
This commit is contained in:
mattias 2017-11-27 21:29:04 +00:00
parent 4a688b6468
commit 2b911c68c1
4 changed files with 137 additions and 46 deletions

View File

@ -230,13 +230,40 @@ const
type
// Procedure Specifiers
TProcedureSpecifier = (
psSTDCALL, psREGISTER, psPOPSTACK, psVIRTUAL, psABSTRACT, psDYNAMIC,
psOVERLOAD, psOVERRIDE, psREINTRODUCE, psCDECL, psINLINE, psMESSAGE,
psEXTERNAL, psFORWARD, psPASCAL, psASSEMBLER, psSAVEREGISTERS,
psFAR, psNEAR, psFINAL, psSTATIC, psMWPASCAL, psNOSTACKFRAME,
psDEPRECATED, psDISPID, psPLATFORM, psSAFECALL, psUNIMPLEMENTED,
psEXPERIMENTAL, psLIBRARY, psENUMERATOR, psVARARGS,
psEdgedBracket);
psStdCall,
psRegister,
psPopStack,
psVirtual,
psAbstract,
psDynamic,
psOverload,
psOverride,
psReintroduce,
psCDecl,
psInline,
psMessage,
psExternal,
psForward,
psPascal,
psAssembler,
psSaveRegisters,
psFar,
psNear,
psFinal,
psStatic,
psMWPascal,
psNoStackframe,
psDeprecated,
psDispID,
psPlatform,
psSafeCall,
psUnimplemented,
psExperimental,
psLibrary,
psEnumerator,
psVarargs,
psEdgedBracket
);
TAllProcedureSpecifiers = set of TProcedureSpecifier;
const

View File

@ -9493,6 +9493,7 @@ var
then
Include(Params.Flags,fdfIgnoreOverloadedProcs);
//debugln(['ResolveIdentifier ',IsEnd,' ',GetAtom(CurAtom),' ',Context.Node.DescAsString,' ',Context.Node.Parent.DescAsString,' ']);
if IsEnd and (Context.Node.Desc=ctnIdentifier)
and (Context.Node.Parent.Desc=ctnAttribParam)
and ResolveAttribute(Context) then begin

View File

@ -42,7 +42,7 @@ interface
{ $DEFINE ShowFoundIdents}
{ $DEFINE ShowFilteredIdents}
{ $DEFINE ShowHistory}
{ $DEFINE VerboseCodeContext}
{$DEFINE VerboseCodeContext}
uses
{$IFDEF MEM_CHECK}
@ -420,6 +420,8 @@ type
out StartInSubContext, HasInheritedKeyword: Boolean);
function CollectAllContexts(Params: TFindDeclarationParams;
const FoundContext: TFindContext): TIdentifierFoundResult;
function CollectAttributeConstructors({%H-}Params: TFindDeclarationParams;
const FoundContext: TFindContext): TIdentifierFoundResult;
procedure AddCollectionContext(Tool: TFindDeclarationTool;
Node: TCodeTreeNode);
function CheckCursorInCompilerDirective(CursorPos: TCodeXYPosition): boolean;
@ -2240,6 +2242,37 @@ begin
AddCollectionContext(FoundContext.Tool,FoundContext.Node);
end;
function TIdentCompletionTool.CollectAttributeConstructors(
Params: TFindDeclarationParams; const FoundContext: TFindContext
): TIdentifierFoundResult;
begin
Result:=ifrProceedSearch;
if FoundContext.Node=nil then exit;
{$IFDEF VerboseCodeContext}
//DebugLn(['TIdentCompletionTool.CollectAttributeConstructors ',FoundContext.Node.DescAsString]);
{$ENDIF}
case FoundContext.Node.Desc of
ctnProcedure:
begin
{$IFDEF VerboseCodeContext}
//DebugLn('TIdentCompletionTool.CollectAttributeConstructors Found Proc ',FoundContext.Tool.ExtractProcName(FoundContext.Node,[]),' ',FoundContext.Tool.CleanPosToStr(FoundContext.Node.StartPos,true));
{$ENDIF}
if (CurrentIdentifierContexts.ProcName='') then exit;
if FoundContext.Tool.NodeIsConstructor(FoundContext.Node) then begin
{$IFDEF VerboseCodeContext}
DebugLn('TIdentCompletionTool.CollectAttributeConstructors Found Constructor ',FoundContext.Tool.ExtractProcName(FoundContext.Node,[]),' ',FoundContext.Tool.CleanPosToStr(FoundContext.Node.StartPos,true));
{$ENDIF}
AddCollectionContext(FoundContext.Tool,FoundContext.Node);
end;
// ToDo: method without 'overload' hides inherited one
//if not FoundContext.Tool.ProcNodeHasSpecifier(FoundContext.Node, psOVERLOAD) then
// Exclude(Params.Flags, fdfSearchInAncestors);
end;
else
exit;
end;
end;
procedure TIdentCompletionTool.AddCollectionContext(Tool: TFindDeclarationTool;
Node: TCodeTreeNode);
begin
@ -3122,20 +3155,29 @@ var
// returns true, on error or context is parameter
var
VarNameAtom, ProcNameAtom: TAtomPosition;
ParameterIndex: integer;
ParameterIndex, StartPos: integer;
ContextExprStartPos: LongInt;
StartInSubContext, HasInheritedKeyword: Boolean;
StartInSubContext, HasInheritedKeyword, IsAttributeParams: Boolean;
ExprType: TExpressionType;
AttribParamNode: TCodeTreeNode;
begin
Result:=false;
// check if in a begin..end block
if CursorNode.GetNodeOfTypes([ctnBeginBlock,ctnInitialization,ctnFinalization])=nil
IsAttributeParams:=false;
if (CursorNode.Desc=ctnParamsRound)
and (CursorNode.Parent.Desc=ctnAttribParam) then begin
IsAttributeParams:=true;
AttribParamNode:=CursorNode.Parent;
StartPos:=AttribParamNode.StartPos;
end else if CursorNode.GetNodeOfTypes([ctnBeginBlock,ctnInitialization,ctnFinalization])<>nil
then begin
DebugLn(['TIdentCompletionTool.FindCodeContext.CheckContextIsParameter not in a begin block']);
StartPos:=CursorNode.StartPos;
end else begin
// not in a begin..end block
DebugLn(['TIdentCompletionTool.FindCodeContext.CheckContextIsParameter not in a begin block "',CursorNode.DescAsString,'"']);
exit;
end;
// check if cursor is in a parameter list
if not CheckParameterSyntax(CursorNode.StartPos, CleanCursorPos,
if not CheckParameterSyntax(StartPos, CleanCursorPos,
VarNameAtom, ProcNameAtom, ParameterIndex)
then begin
if VarNameAtom.StartPos=0 then ;
@ -3153,8 +3195,6 @@ var
CurrentIdentifierContexts.ProcNameAtom:=ProcNameAtom;
CurrentIdentifierContexts.ProcName:=GetAtom(ProcNameAtom);
AddPredefinedProcs(CurrentIdentifierContexts,ProcNameAtom);
MoveCursorToAtomPos(ProcNameAtom);
ReadNextAtom; // read opening bracket
CurrentIdentifierContexts.StartPos:=CurPos.EndPos;
@ -3164,39 +3204,62 @@ var
else
CurrentIdentifierContexts.EndPos:=SrcLen+1;
FindCollectionContext(Params,ProcNameAtom.StartPos,CursorNode,
ExprType,ContextExprStartPos,StartInSubContext,
HasInheritedKeyword);
if IsAttributeParams then begin
debugln(['CheckContextIsParameter AttribParamNode={',ExtractNode(AttribParamNode,[]),'}']);
Params.Flags:=fdfDefaultForExpressions+[fdfSkipClassForward];
Params.Identifier:=@Src[ProcNameAtom.StartPos];
Params.ContextNode:=AttribParamNode.FirstChild;
ExprType:=FindExpressionTypeOfTerm(AttribParamNode.StartPos,ProcNameAtom.EndPos,Params,false);
{$IFDEF VerboseCodeContext}
debugln(['CheckContextIsParameter Attribute: ',ExprTypeToString(ExprType)]);
{$ENDIF}
if (ExprType.Context.Node = nil) or (ExprType.Context.Tool = nil) then
exit;
CurrentIdentifierList.Context:=ExprType.Context;
Params.ContextNode:=ExprType.Context.Node;
Params.Flags:=[fdfSearchInAncestors,fdfCollect,fdfFindVariable,fdfSearchInHelpers];
Params.SetIdentifier(Self,'*',@CollectAttributeConstructors);
ExprType.Context.Tool.FindIdentifierInContext(Params);
end else begin
AddPredefinedProcs(CurrentIdentifierContexts,ProcNameAtom);
FindCollectionContext(Params,ProcNameAtom.StartPos,CursorNode,
ExprType,ContextExprStartPos,StartInSubContext,
HasInheritedKeyword);
if ContextExprStartPos=0 then ;
{$IFDEF VerboseCodeContext}
DebugLn(['CheckContextIsParameter StartInSubContext=',StartInSubContext,' ',ExprType.Context.Node.DescAsString,' "',copy(ExprType.Context.Tool.Src,GatherContext.Node.StartPos-20,25),'"']);
{$ENDIF}
// gather declarations of all parameter lists
if (ExprType.Context.Node = nil) or (ExprType.Context.Tool = nil) then
begin
if ExprType.Desc in xtAllIdentPredefinedTypes then
if ContextExprStartPos=0 then ;
{$IFDEF VerboseCodeContext}
DebugLn(['CheckContextIsParameter StartInSubContext=',StartInSubContext,' ',ExprTypeToString(ExprType),' "',copy(ExprType.Context.Tool.Src,ExprType.Context.Node.StartPos-20,25),'"']);
{$ENDIF}
if (ExprType.Context.Node = nil) or (ExprType.Context.Tool = nil) then
begin
ExprType.Context.Node := CursorNode;
ExprType.Context.Tool := Self;
end else
Exit;
if ExprType.Desc in xtAllIdentPredefinedTypes then
begin
ExprType.Context.Node := CursorNode;
ExprType.Context.Tool := Self;
end else
Exit;
end;
Params.ContextNode:=ExprType.Context.Node;
if IsAttributeParams then begin
Params.SetIdentifier(Self,'*',@CollectAttributeConstructors);
end else begin
Params.SetIdentifier(Self,@Src[ProcNameAtom.StartPos],@CollectAllContexts);
end;
Params.Flags:=[fdfSearchInAncestors,fdfCollect,fdfFindVariable,fdfSearchInHelpers];
if not StartInSubContext then
Include(Params.Flags,fdfSearchInParentNodes);
CurrentIdentifierList.Context:=ExprType.Context;
{$IFDEF VerboseCodeContext}
DebugLn('CheckContextIsParameter searching procedures, properties and variables ...');
{$ENDIF}
if ExprType.Desc in xtAllTypeHelperTypes then
ExprType.Context.Tool.FindIdentifierInBasicTypeHelpers(ExprType.Desc, Params)
else
ExprType.Context.Tool.FindIdentifierInContext(Params);
end;
Params.ContextNode:=ExprType.Context.Node;
Params.SetIdentifier(Self,@Src[ProcNameAtom.StartPos],@CollectAllContexts);
Params.Flags:=[fdfSearchInAncestors,fdfCollect,fdfFindVariable,fdfSearchInHelpers];
if not StartInSubContext then
Include(Params.Flags,fdfSearchInParentNodes);
CurrentIdentifierList.Context:=ExprType.Context;
{$IFDEF VerboseCodeContext}
DebugLn('CheckContextIsParameter searching procedures, properties and variables ...');
{$ENDIF}
if ExprType.Desc in xtAllTypeHelperTypes then
ExprType.Context.Tool.FindIdentifierInBasicTypeHelpers(ExprType.Desc, Params)
else
ExprType.Context.Tool.FindIdentifierInContext(Params);
// gather declarations of all parameter lists
{$IFDEF VerboseCodeContext}
DebugLn('CheckContextIsParameter END');
{$ENDIF}

View File

@ -4210,7 +4210,7 @@ begin
ReadTypeReference(true);
if CurPos.Flag=cafRoundBracketOpen then begin
CreateChildNode;
CurNode.Desc:=ctnAttribParam;
CurNode.Desc:=ctnParamsRound;
ReadTilBracketClose(true);
CurNode.EndPos:=CurPos.EndPos;
EndChildNode;