mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-23 20:09:27 +02:00
codetools: simplified gathering helpers, patch #28794 from Ondrej Pokorny
git-svn-id: trunk@49991 -
This commit is contained in:
parent
3cabc3eba0
commit
bd020c787f
@ -560,7 +560,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
Params:=TFindDeclarationParams.Create(Self,ContextNode);
|
Params:=TFindDeclarationParams.Create(Self,ContextNode);
|
||||||
try
|
try
|
||||||
FindHelpersInContext(Params);
|
|
||||||
Params.SetIdentifier(Self,@TypeName[1],nil);
|
Params.SetIdentifier(Self,@TypeName[1],nil);
|
||||||
Params.Flags:=[fdfExceptionOnNotFound,fdfSearchInParentNodes];
|
Params.Flags:=[fdfExceptionOnNotFound,fdfSearchInParentNodes];
|
||||||
//DebugLn(['TEventsCodeTool.FindMethodTypeInfo TypeName=',TypeName,' MainFilename=',MainFilename]);
|
//DebugLn(['TEventsCodeTool.FindMethodTypeInfo TypeName=',TypeName,' MainFilename=',MainFilename]);
|
||||||
|
@ -2524,234 +2524,236 @@ begin
|
|||||||
Result:=false;
|
Result:=false;
|
||||||
|
|
||||||
ActivateGlobalWriteLock;
|
ActivateGlobalWriteLock;
|
||||||
InitCollectIdentifiers(CursorPos,IdentifierList);
|
|
||||||
IdentStartXY:=FindIdentifierStartPos(CursorPos);
|
|
||||||
if CheckCursorInCompilerDirective(IdentStartXY) then exit(true);
|
|
||||||
|
|
||||||
ParseSourceTillCollectionStart(IdentStartXY,CleanCursorPos,CursorNode,
|
|
||||||
IdentStartPos,IdentEndPos);
|
|
||||||
Params:=TFindDeclarationParams.Create(Self,CursorNode);
|
|
||||||
try
|
try
|
||||||
FindHelpersInContext(Params);
|
InitCollectIdentifiers(CursorPos,IdentifierList);
|
||||||
if CleanCursorPos=0 then ;
|
IdentStartXY:=FindIdentifierStartPos(CursorPos);
|
||||||
if IdentStartPos>0 then begin
|
if CheckCursorInCompilerDirective(IdentStartXY) then exit(true);
|
||||||
MoveCursorToCleanPos(IdentStartPos);
|
|
||||||
ReadNextAtom;
|
|
||||||
CurrentIdentifierList.StartAtom:=CurPos;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// find context
|
ParseSourceTillCollectionStart(IdentStartXY,CleanCursorPos,CursorNode,
|
||||||
{$IFDEF CTDEBUG}
|
IdentStartPos,IdentEndPos);
|
||||||
DebugLn('TIdentCompletionTool.GatherIdentifiers B',
|
Params:=TFindDeclarationParams.Create(Self,CursorNode);
|
||||||
' CleanCursorPos=',CleanPosToStr(CleanCursorPos),
|
try
|
||||||
' IdentStartPos=',CleanPosToStr(IdentStartPos),' IdentEndPos=',CleanPosToStr(IdentEndPos),
|
if CleanCursorPos=0 then ;
|
||||||
' Ident=',copy(Src,IdentStartPos,IdentEndPos-IdentStartPos));
|
if IdentStartPos>0 then begin
|
||||||
{$ENDIF}
|
MoveCursorToCleanPos(IdentStartPos);
|
||||||
GatherContext:=CreateFindContext(Self,CursorNode);
|
|
||||||
CurrentIdentifierList.NewMemberVisibility:=GetClassVisibility(CursorNode);
|
|
||||||
if CursorNode.Desc in [ctnUsesSection,ctnUseUnit] then begin
|
|
||||||
GatherUnitNames;
|
|
||||||
MoveCursorToCleanPos(IdentEndPos);
|
|
||||||
ReadNextAtom;
|
|
||||||
if (CurPos.Flag=cafWord) and (not UpAtomIs('IN')) then begin
|
|
||||||
// add comma
|
|
||||||
CurrentIdentifierList.ContextFlags:=
|
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfNeedsEndComma];
|
|
||||||
end;
|
|
||||||
end else if (CursorNode.Desc in AllSourceTypes)
|
|
||||||
and (PositionsInSameLine(Src,CursorNode.StartPos,IdentStartPos)) then begin
|
|
||||||
GatherSourceNames(GatherContext);
|
|
||||||
end else begin
|
|
||||||
FindCollectionContext(Params,IdentStartPos,CursorNode,
|
|
||||||
ExprType,ContextExprStartPos,StartInSubContext);
|
|
||||||
|
|
||||||
GatherContext := ExprType.Context;
|
|
||||||
// find class and ancestors if existing (needed for protected identifiers)
|
|
||||||
if GatherContext.Tool = Self then
|
|
||||||
FindContextClassAndAncestors(IdentStartXY, FICTClassAndAncestors);
|
|
||||||
|
|
||||||
CursorContext:=CreateFindContext(Self,CursorNode);
|
|
||||||
GatherContextKeywords(CursorContext,IdentStartPos,Beautifier);
|
|
||||||
|
|
||||||
// check for incomplete context
|
|
||||||
|
|
||||||
// context bracket level
|
|
||||||
CurrentIdentifierList.StartBracketLvl:=
|
|
||||||
GetBracketLvl(Src,CursorNode.StartPos,IdentStartPos,
|
|
||||||
Scanner.NestedComments);
|
|
||||||
if CursorNode.Desc in AllPascalStatements then begin
|
|
||||||
CurrentIdentifierList.ContextFlags:=
|
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfStartInStatement];
|
|
||||||
end;
|
|
||||||
|
|
||||||
// context in front of
|
|
||||||
StartPosOfVariable:=FindStartOfTerm(IdentStartPos,NodeTermInType(CursorNode));
|
|
||||||
if StartPosOfVariable>0 then begin
|
|
||||||
if StartPosOfVariable=IdentStartPos then begin
|
|
||||||
// cursor is at start of an operand
|
|
||||||
CurrentIdentifierList.ContextFlags:=
|
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfStartOfOperand];
|
|
||||||
end else begin
|
|
||||||
MoveCursorToCleanPos(IdentStartPos);
|
|
||||||
ReadPriorAtom;
|
|
||||||
if CurPos.Flag=cafPoint then
|
|
||||||
// cursor is behind a point
|
|
||||||
CurrentIdentifierList.ContextFlags:=
|
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfStartIsSubIdent];
|
|
||||||
end;
|
|
||||||
MoveCursorToCleanPos(StartPosOfVariable);
|
|
||||||
ReadPriorAtom;
|
|
||||||
CurrentIdentifierList.StartAtomInFront:=CurPos;
|
|
||||||
if (ilcfStartInStatement in CurrentIdentifierList.ContextFlags)
|
|
||||||
then begin
|
|
||||||
// check if LValue
|
|
||||||
if (CurPos.Flag in [cafSemicolon,cafEnd,cafColon])
|
|
||||||
or UpAtomIs('BEGIN')
|
|
||||||
or UpAtomIs('TRY') or UpAtomIs('FINALLY') or UpAtomIs('EXCEPT')
|
|
||||||
or UpAtomIs('FOR') or UpAtomIs('DO') or UpAtomIs('THEN')
|
|
||||||
or UpAtomIs('REPEAT') or UpAtomIs('ASM') or UpAtomIs('ELSE')
|
|
||||||
then begin
|
|
||||||
CurrentIdentifierList.ContextFlags:=
|
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfStartOfStatement];
|
|
||||||
end;
|
|
||||||
// check if expression
|
|
||||||
if UpAtomIs('IF') or UpAtomIs('CASE') or UpAtomIs('WHILE')
|
|
||||||
or UpAtomIs('UNTIL')
|
|
||||||
then begin
|
|
||||||
// todo: check at start of expression, not only in front of variable
|
|
||||||
CurrentIdentifierList.ContextFlags:=
|
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfIsExpression, ilcfDontAllowProcedures];
|
|
||||||
end;
|
|
||||||
// check if procedure is allowed
|
|
||||||
if CurPos.Flag in [cafComma, cafRoundBracketOpen, cafEdgedBracketOpen, cafEqual, cafOtherOperator] then
|
|
||||||
CurrentIdentifierList.ContextFlags:=
|
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfDontAllowProcedures];
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
// context behind
|
|
||||||
if (IdentEndPos<SrcLen) then begin
|
|
||||||
MoveCursorToCleanPos(IdentEndPos);
|
|
||||||
//debugln(['TIdentCompletionTool.GatherIdentifiers "',dbgstr(Src,IdentStartPos,IdentEndPos-IdentStartPos),'"']);
|
|
||||||
InFrontOfDirective:=(CurPos.StartPos<SrcLen) and (Src[CurPos.StartPos]='{')
|
|
||||||
and (Src[CurPos.StartPos+1]='$');
|
|
||||||
ReadNextAtom;
|
ReadNextAtom;
|
||||||
|
CurrentIdentifierList.StartAtom:=CurPos;
|
||||||
|
end;
|
||||||
|
|
||||||
// check end of line
|
// find context
|
||||||
if (not InFrontOfDirective)
|
{$IFDEF CTDEBUG}
|
||||||
and (CursorPos.Code.LineColIsOutside(CursorPos.Y,CursorPos.X)
|
DebugLn('TIdentCompletionTool.GatherIdentifiers B',
|
||||||
or (not PositionsInSameLine(Src,IdentEndPos,CurPos.StartPos)))
|
' CleanCursorPos=',CleanPosToStr(CleanCursorPos),
|
||||||
then
|
' IdentStartPos=',CleanPosToStr(IdentStartPos),' IdentEndPos=',CleanPosToStr(IdentEndPos),
|
||||||
|
' Ident=',copy(Src,IdentStartPos,IdentEndPos-IdentStartPos));
|
||||||
|
{$ENDIF}
|
||||||
|
GatherContext:=CreateFindContext(Self,CursorNode);
|
||||||
|
CurrentIdentifierList.NewMemberVisibility:=GetClassVisibility(CursorNode);
|
||||||
|
if CursorNode.Desc in [ctnUsesSection,ctnUseUnit] then begin
|
||||||
|
GatherUnitNames;
|
||||||
|
MoveCursorToCleanPos(IdentEndPos);
|
||||||
|
ReadNextAtom;
|
||||||
|
if (CurPos.Flag=cafWord) and (not UpAtomIs('IN')) then begin
|
||||||
|
// add comma
|
||||||
CurrentIdentifierList.ContextFlags:=
|
CurrentIdentifierList.ContextFlags:=
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfEndOfLine];
|
CurrentIdentifierList.ContextFlags+[ilcfNeedsEndComma];
|
||||||
|
|
||||||
CurrentIdentifierList.StartAtomBehind:=CurPos;
|
|
||||||
// check if a semicolon is needed or forbidden at the end
|
|
||||||
if InFrontOfDirective
|
|
||||||
or (CurrentIdentifierList.StartBracketLvl>0)
|
|
||||||
or (CurPos.Flag in [cafSemicolon, cafEqual, cafColon, cafComma,
|
|
||||||
cafPoint, cafRoundBracketOpen, cafRoundBracketClose,
|
|
||||||
cafEdgedBracketOpen, cafEdgedBracketClose])
|
|
||||||
or ((CurPos.Flag in [cafWord,cafNone])
|
|
||||||
and (UpAtomIs('ELSE')
|
|
||||||
or UpAtomIs('THEN')
|
|
||||||
or UpAtomIs('DO')
|
|
||||||
or UpAtomIs('TO')
|
|
||||||
or UpAtomIs('OF')
|
|
||||||
or WordIsBinaryOperator.DoItCaseInsensitive(Src,
|
|
||||||
CurPos.StartPos,CurPos.EndPos-CurPos.StartPos)))
|
|
||||||
then begin
|
|
||||||
// do not add semicolon
|
|
||||||
CurrentIdentifierList.ContextFlags:=
|
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfNoEndSemicolon];
|
|
||||||
end;
|
end;
|
||||||
// check if in statement
|
end else if (CursorNode.Desc in AllSourceTypes)
|
||||||
if (ilcfStartInStatement in CurrentIdentifierList.ContextFlags) then
|
and (PositionsInSameLine(Src,CursorNode.StartPos,IdentStartPos)) then begin
|
||||||
begin
|
GatherSourceNames(GatherContext);
|
||||||
// check if a semicolon is needed at the end
|
end else begin
|
||||||
if (not (ilcfNoEndSemicolon in CurrentIdentifierList.ContextFlags))
|
FindCollectionContext(Params,IdentStartPos,CursorNode,
|
||||||
then begin
|
ExprType,ContextExprStartPos,StartInSubContext);
|
||||||
// check if a semicolon is needed at the end
|
|
||||||
if (CurPos.Flag in [cafEnd])
|
GatherContext := ExprType.Context;
|
||||||
or WordIsBlockKeyWord.DoItCaseInsensitive(Src,
|
// find class and ancestors if existing (needed for protected identifiers)
|
||||||
CurPos.StartPos,CurPos.EndPos-CurPos.StartPos)
|
if GatherContext.Tool = Self then
|
||||||
or ((CurPos.Flag=cafWord)
|
FindContextClassAndAncestors(IdentStartXY, FICTClassAndAncestors);
|
||||||
and (not PositionsInSameLine(Src,IdentEndPos,CurPos.StartPos)))
|
|
||||||
then begin
|
CursorContext:=CreateFindContext(Self,CursorNode);
|
||||||
// add semicolon
|
GatherContextKeywords(CursorContext,IdentStartPos,Beautifier);
|
||||||
|
|
||||||
|
// check for incomplete context
|
||||||
|
|
||||||
|
// context bracket level
|
||||||
|
CurrentIdentifierList.StartBracketLvl:=
|
||||||
|
GetBracketLvl(Src,CursorNode.StartPos,IdentStartPos,
|
||||||
|
Scanner.NestedComments);
|
||||||
|
if CursorNode.Desc in AllPascalStatements then begin
|
||||||
|
CurrentIdentifierList.ContextFlags:=
|
||||||
|
CurrentIdentifierList.ContextFlags+[ilcfStartInStatement];
|
||||||
|
end;
|
||||||
|
|
||||||
|
// context in front of
|
||||||
|
StartPosOfVariable:=FindStartOfTerm(IdentStartPos,NodeTermInType(CursorNode));
|
||||||
|
if StartPosOfVariable>0 then begin
|
||||||
|
if StartPosOfVariable=IdentStartPos then begin
|
||||||
|
// cursor is at start of an operand
|
||||||
|
CurrentIdentifierList.ContextFlags:=
|
||||||
|
CurrentIdentifierList.ContextFlags+[ilcfStartOfOperand];
|
||||||
|
end else begin
|
||||||
|
MoveCursorToCleanPos(IdentStartPos);
|
||||||
|
ReadPriorAtom;
|
||||||
|
if CurPos.Flag=cafPoint then
|
||||||
|
// cursor is behind a point
|
||||||
CurrentIdentifierList.ContextFlags:=
|
CurrentIdentifierList.ContextFlags:=
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfNeedsEndSemicolon];
|
CurrentIdentifierList.ContextFlags+[ilcfStartIsSubIdent];
|
||||||
|
end;
|
||||||
|
MoveCursorToCleanPos(StartPosOfVariable);
|
||||||
|
ReadPriorAtom;
|
||||||
|
CurrentIdentifierList.StartAtomInFront:=CurPos;
|
||||||
|
if (ilcfStartInStatement in CurrentIdentifierList.ContextFlags)
|
||||||
|
then begin
|
||||||
|
// check if LValue
|
||||||
|
if (CurPos.Flag in [cafSemicolon,cafEnd,cafColon])
|
||||||
|
or UpAtomIs('BEGIN')
|
||||||
|
or UpAtomIs('TRY') or UpAtomIs('FINALLY') or UpAtomIs('EXCEPT')
|
||||||
|
or UpAtomIs('FOR') or UpAtomIs('DO') or UpAtomIs('THEN')
|
||||||
|
or UpAtomIs('REPEAT') or UpAtomIs('ASM') or UpAtomIs('ELSE')
|
||||||
|
then begin
|
||||||
|
CurrentIdentifierList.ContextFlags:=
|
||||||
|
CurrentIdentifierList.ContextFlags+[ilcfStartOfStatement];
|
||||||
|
end;
|
||||||
|
// check if expression
|
||||||
|
if UpAtomIs('IF') or UpAtomIs('CASE') or UpAtomIs('WHILE')
|
||||||
|
or UpAtomIs('UNTIL')
|
||||||
|
then begin
|
||||||
|
// todo: check at start of expression, not only in front of variable
|
||||||
|
CurrentIdentifierList.ContextFlags:=
|
||||||
|
CurrentIdentifierList.ContextFlags+[ilcfIsExpression, ilcfDontAllowProcedures];
|
||||||
|
end;
|
||||||
|
// check if procedure is allowed
|
||||||
|
if CurPos.Flag in [cafComma, cafRoundBracketOpen, cafEdgedBracketOpen, cafEqual, cafOtherOperator] then
|
||||||
|
CurrentIdentifierList.ContextFlags:=
|
||||||
|
CurrentIdentifierList.ContextFlags+[ilcfDontAllowProcedures];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
// context behind
|
||||||
|
if (IdentEndPos<SrcLen) then begin
|
||||||
|
MoveCursorToCleanPos(IdentEndPos);
|
||||||
|
//debugln(['TIdentCompletionTool.GatherIdentifiers "',dbgstr(Src,IdentStartPos,IdentEndPos-IdentStartPos),'"']);
|
||||||
|
InFrontOfDirective:=(CurPos.StartPos<SrcLen) and (Src[CurPos.StartPos]='{')
|
||||||
|
and (Src[CurPos.StartPos+1]='$');
|
||||||
|
ReadNextAtom;
|
||||||
|
|
||||||
|
// check end of line
|
||||||
|
if (not InFrontOfDirective)
|
||||||
|
and (CursorPos.Code.LineColIsOutside(CursorPos.Y,CursorPos.X)
|
||||||
|
or (not PositionsInSameLine(Src,IdentEndPos,CurPos.StartPos)))
|
||||||
|
then
|
||||||
|
CurrentIdentifierList.ContextFlags:=
|
||||||
|
CurrentIdentifierList.ContextFlags+[ilcfEndOfLine];
|
||||||
|
|
||||||
|
CurrentIdentifierList.StartAtomBehind:=CurPos;
|
||||||
|
// check if a semicolon is needed or forbidden at the end
|
||||||
|
if InFrontOfDirective
|
||||||
|
or (CurrentIdentifierList.StartBracketLvl>0)
|
||||||
|
or (CurPos.Flag in [cafSemicolon, cafEqual, cafColon, cafComma,
|
||||||
|
cafPoint, cafRoundBracketOpen, cafRoundBracketClose,
|
||||||
|
cafEdgedBracketOpen, cafEdgedBracketClose])
|
||||||
|
or ((CurPos.Flag in [cafWord,cafNone])
|
||||||
|
and (UpAtomIs('ELSE')
|
||||||
|
or UpAtomIs('THEN')
|
||||||
|
or UpAtomIs('DO')
|
||||||
|
or UpAtomIs('TO')
|
||||||
|
or UpAtomIs('OF')
|
||||||
|
or WordIsBinaryOperator.DoItCaseInsensitive(Src,
|
||||||
|
CurPos.StartPos,CurPos.EndPos-CurPos.StartPos)))
|
||||||
|
then begin
|
||||||
|
// do not add semicolon
|
||||||
|
CurrentIdentifierList.ContextFlags:=
|
||||||
|
CurrentIdentifierList.ContextFlags+[ilcfNoEndSemicolon];
|
||||||
|
end;
|
||||||
|
// check if in statement
|
||||||
|
if (ilcfStartInStatement in CurrentIdentifierList.ContextFlags) then
|
||||||
|
begin
|
||||||
|
// check if a semicolon is needed at the end
|
||||||
|
if (not (ilcfNoEndSemicolon in CurrentIdentifierList.ContextFlags))
|
||||||
|
then begin
|
||||||
|
// check if a semicolon is needed at the end
|
||||||
|
if (CurPos.Flag in [cafEnd])
|
||||||
|
or WordIsBlockKeyWord.DoItCaseInsensitive(Src,
|
||||||
|
CurPos.StartPos,CurPos.EndPos-CurPos.StartPos)
|
||||||
|
or ((CurPos.Flag=cafWord)
|
||||||
|
and (not PositionsInSameLine(Src,IdentEndPos,CurPos.StartPos)))
|
||||||
|
then begin
|
||||||
|
// add semicolon
|
||||||
|
CurrentIdentifierList.ContextFlags:=
|
||||||
|
CurrentIdentifierList.ContextFlags+[ilcfNeedsEndSemicolon];
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
// check missing 'do' after 'with'
|
||||||
// check missing 'do' after 'with'
|
if CurrentIdentifierList.StartUpAtomInFrontIs('WITH')
|
||||||
if CurrentIdentifierList.StartUpAtomInFrontIs('WITH')
|
and (not CurrentIdentifierList.StartUpAtomBehindIs('DO'))
|
||||||
and (not CurrentIdentifierList.StartUpAtomBehindIs('DO'))
|
and (CurrentIdentifierList.StartBracketLvl=0)
|
||||||
and (CurrentIdentifierList.StartBracketLvl=0)
|
and (not (CurrentIdentifierList.StartAtomBehind.Flag in
|
||||||
and (not (CurrentIdentifierList.StartAtomBehind.Flag in
|
[cafComma,cafPoint,cafRoundBracketOpen,cafEdgedBracketOpen]))
|
||||||
[cafComma,cafPoint,cafRoundBracketOpen,cafEdgedBracketOpen]))
|
and (not CurrentIdentifierList.StartUpAtomBehindIs('^'))
|
||||||
and (not CurrentIdentifierList.StartUpAtomBehindIs('^'))
|
then
|
||||||
then
|
CurrentIdentifierList.ContextFlags:=
|
||||||
|
CurrentIdentifierList.ContextFlags+[ilcfNeedsDo];
|
||||||
|
end else begin
|
||||||
|
// end of source
|
||||||
CurrentIdentifierList.ContextFlags:=
|
CurrentIdentifierList.ContextFlags:=
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfNeedsDo];
|
CurrentIdentifierList.ContextFlags+[ilcfEndOfLine];
|
||||||
end else begin
|
end;
|
||||||
// end of source
|
|
||||||
CurrentIdentifierList.ContextFlags:=
|
// search and gather identifiers in context
|
||||||
CurrentIdentifierList.ContextFlags+[ilcfEndOfLine];
|
if (GatherContext.Tool<>nil) and (GatherContext.Node<>nil) then begin
|
||||||
|
{$IFDEF CTDEBUG}
|
||||||
|
DebugLn('TIdentCompletionTool.GatherIdentifiers D CONTEXT: ',
|
||||||
|
GatherContext.Tool.MainFilename,
|
||||||
|
' ',GatherContext.Node.DescAsString,
|
||||||
|
' "',StringToPascalConst(copy(GatherContext.Tool.Src,GatherContext.Node.StartPos,50)),'"');
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
|
// gather all identifiers in context
|
||||||
|
Params.ContextNode:=GatherContext.Node;
|
||||||
|
Params.SetIdentifier(Self,nil,@CollectAllIdentifiers);
|
||||||
|
Params.Flags:=[fdfSearchInAncestors,fdfCollect,fdfFindVariable,fdfSearchInHelpers];
|
||||||
|
if (Params.ContextNode.Desc=ctnInterface) and StartInSubContext then
|
||||||
|
Include(Params.Flags,fdfIgnoreUsedUnits);
|
||||||
|
if not StartInSubContext then
|
||||||
|
Include(Params.Flags,fdfSearchInParentNodes);
|
||||||
|
if Params.ContextNode.Desc in AllClasses then
|
||||||
|
Exclude(Params.Flags,fdfSearchInParentNodes);
|
||||||
|
{$IFDEF CTDEBUG}
|
||||||
|
DebugLn('TIdentCompletionTool.GatherIdentifiers F');
|
||||||
|
{$ENDIF}
|
||||||
|
CurrentIdentifierList.Context:=GatherContext;
|
||||||
|
if GatherContext.Node.Desc=ctnIdentifier then
|
||||||
|
Params.Flags:=Params.Flags+[fdfIgnoreCurContextNode];
|
||||||
|
GatherContext.Tool.FindIdentifierInContext(Params);
|
||||||
|
end else
|
||||||
|
if ExprType.Desc in xtAllIdentPredefinedTypes then
|
||||||
|
begin
|
||||||
|
// gather all identifiers in cursor context for basic types (strings etc.)
|
||||||
|
Params.ContextNode:=CursorNode;
|
||||||
|
Params.SetIdentifier(Self,nil,@CollectAllIdentifiers);
|
||||||
|
Params.Flags:=[fdfSearchInAncestors,fdfCollect,fdfFindVariable,fdfSearchInHelpers];
|
||||||
|
CurrentIdentifierList.Context:=GatherContext;
|
||||||
|
FindIdentifierInBasicTypeHelpers(ExprType.Desc, Params);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// check for procedure/method declaration context
|
||||||
|
CheckProcedureDeclarationContext;
|
||||||
|
|
||||||
|
// add useful identifiers
|
||||||
|
{$IFDEF CTDEBUG}
|
||||||
|
DebugLn('TIdentCompletionTool.GatherIdentifiers G');
|
||||||
|
{$ENDIF}
|
||||||
|
GatherUsefulIdentifiers(IdentStartPos,CursorContext,GatherContext);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// search and gather identifiers in context
|
Result:=true;
|
||||||
if (GatherContext.Tool<>nil) and (GatherContext.Node<>nil) then begin
|
finally
|
||||||
{$IFDEF CTDEBUG}
|
FreeListOfPFindContext(FICTClassAndAncestors);
|
||||||
DebugLn('TIdentCompletionTool.GatherIdentifiers D CONTEXT: ',
|
FreeAndNil(FIDCTFoundPublicProperties);
|
||||||
GatherContext.Tool.MainFilename,
|
Params.Free;
|
||||||
' ',GatherContext.Node.DescAsString,
|
ClearIgnoreErrorAfter;
|
||||||
' "',StringToPascalConst(copy(GatherContext.Tool.Src,GatherContext.Node.StartPos,50)),'"');
|
|
||||||
{$ENDIF}
|
|
||||||
|
|
||||||
// gather all identifiers in context
|
|
||||||
Params.ContextNode:=GatherContext.Node;
|
|
||||||
Params.SetIdentifier(Self,nil,@CollectAllIdentifiers);
|
|
||||||
Params.Flags:=[fdfSearchInAncestors,fdfCollect,fdfFindVariable,fdfSearchInHelpers];
|
|
||||||
if (Params.ContextNode.Desc=ctnInterface) and StartInSubContext then
|
|
||||||
Include(Params.Flags,fdfIgnoreUsedUnits);
|
|
||||||
if not StartInSubContext then
|
|
||||||
Include(Params.Flags,fdfSearchInParentNodes);
|
|
||||||
if Params.ContextNode.Desc in AllClasses then
|
|
||||||
Exclude(Params.Flags,fdfSearchInParentNodes);
|
|
||||||
{$IFDEF CTDEBUG}
|
|
||||||
DebugLn('TIdentCompletionTool.GatherIdentifiers F');
|
|
||||||
{$ENDIF}
|
|
||||||
CurrentIdentifierList.Context:=GatherContext;
|
|
||||||
if GatherContext.Node.Desc=ctnIdentifier then
|
|
||||||
Params.Flags:=Params.Flags+[fdfIgnoreCurContextNode];
|
|
||||||
GatherContext.Tool.FindIdentifierInContext(Params);
|
|
||||||
end else
|
|
||||||
if ExprType.Desc in xtAllIdentPredefinedTypes then
|
|
||||||
begin
|
|
||||||
// gather all identifiers in cursor context for basic types (strings etc.)
|
|
||||||
Params.ContextNode:=CursorNode;
|
|
||||||
Params.SetIdentifier(Self,nil,@CollectAllIdentifiers);
|
|
||||||
Params.Flags:=[fdfSearchInAncestors,fdfCollect,fdfFindVariable,fdfSearchInHelpers];
|
|
||||||
CurrentIdentifierList.Context:=GatherContext;
|
|
||||||
FindIdentifierInBasicTypeHelpers(ExprType.Desc, Params);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// check for procedure/method declaration context
|
|
||||||
CheckProcedureDeclarationContext;
|
|
||||||
|
|
||||||
// add useful identifiers
|
|
||||||
{$IFDEF CTDEBUG}
|
|
||||||
DebugLn('TIdentCompletionTool.GatherIdentifiers G');
|
|
||||||
{$ENDIF}
|
|
||||||
GatherUsefulIdentifiers(IdentStartPos,CursorContext,GatherContext);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result:=true;
|
|
||||||
finally
|
finally
|
||||||
FreeListOfPFindContext(FICTClassAndAncestors);
|
|
||||||
FreeAndNil(FIDCTFoundPublicProperties);
|
|
||||||
Params.Free;
|
|
||||||
ClearIgnoreErrorAfter;
|
|
||||||
DeactivateGlobalWriteLock;
|
DeactivateGlobalWriteLock;
|
||||||
CurrentIdentifierList:=nil;
|
CurrentIdentifierList:=nil;
|
||||||
end;
|
end;
|
||||||
@ -2937,43 +2939,44 @@ begin
|
|||||||
CurrentIdentifierContexts:=CodeContexts;
|
CurrentIdentifierContexts:=CodeContexts;
|
||||||
|
|
||||||
ActivateGlobalWriteLock;
|
ActivateGlobalWriteLock;
|
||||||
Params:=TFindDeclarationParams.Create;//FindHelpersInContext called later
|
|
||||||
try
|
try
|
||||||
InitCollectIdentifiers(CursorPos,IdentifierList);
|
InitCollectIdentifiers(CursorPos,IdentifierList);
|
||||||
ParseSourceTillCollectionStart(CursorPos,CleanCursorPos,CursorNode,
|
ParseSourceTillCollectionStart(CursorPos,CleanCursorPos,CursorNode,
|
||||||
IdentStartPos,IdentEndPos);
|
IdentStartPos,IdentEndPos);
|
||||||
Params.ContextNode:=CursorNode;
|
Params:=TFindDeclarationParams.Create(Self, CursorNode);
|
||||||
FindHelpersInContext(Params);
|
try
|
||||||
if IdentStartPos=0 then ;
|
if IdentStartPos=0 then ;
|
||||||
if IdentEndPos=0 then ;
|
if IdentEndPos=0 then ;
|
||||||
|
|
||||||
// find class and ancestors if existing (needed for protected identifiers)
|
// find class and ancestors if existing (needed for protected identifiers)
|
||||||
FindContextClassAndAncestors(CursorPos,FICTClassAndAncestors);
|
FindContextClassAndAncestors(CursorPos,FICTClassAndAncestors);
|
||||||
|
|
||||||
if CursorNode<>nil then begin
|
if CursorNode<>nil then begin
|
||||||
if not CheckContextIsParameter(Result) then begin
|
if not CheckContextIsParameter(Result) then begin
|
||||||
DebugLn(['TIdentCompletionTool.FindCodeContext cursor not at parameter']);
|
DebugLn(['TIdentCompletionTool.FindCodeContext cursor not at parameter']);
|
||||||
exit;
|
exit;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
|
||||||
|
|
||||||
if CurrentIdentifierContexts=nil then begin
|
if CurrentIdentifierContexts=nil then begin
|
||||||
// create default
|
// create default
|
||||||
AddCollectionContext(Self,CursorNode);
|
AddCollectionContext(Self,CursorNode);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Result:=true;
|
Result:=true;
|
||||||
|
finally
|
||||||
|
if Result then begin
|
||||||
|
CodeContexts:=CurrentIdentifierContexts;
|
||||||
|
CurrentIdentifierContexts:=nil;
|
||||||
|
end else begin
|
||||||
|
FreeAndNil(CurrentIdentifierContexts);
|
||||||
|
end;
|
||||||
|
FreeListOfPFindContext(FICTClassAndAncestors);
|
||||||
|
FreeAndNil(FIDCTFoundPublicProperties);
|
||||||
|
Params.Free;
|
||||||
|
ClearIgnoreErrorAfter;
|
||||||
|
end;
|
||||||
finally
|
finally
|
||||||
if Result then begin
|
|
||||||
CodeContexts:=CurrentIdentifierContexts;
|
|
||||||
CurrentIdentifierContexts:=nil;
|
|
||||||
end else begin
|
|
||||||
FreeAndNil(CurrentIdentifierContexts);
|
|
||||||
end;
|
|
||||||
FreeListOfPFindContext(FICTClassAndAncestors);
|
|
||||||
FreeAndNil(FIDCTFoundPublicProperties);
|
|
||||||
Params.Free;
|
|
||||||
ClearIgnoreErrorAfter;
|
|
||||||
DeactivateGlobalWriteLock;
|
DeactivateGlobalWriteLock;
|
||||||
FreeAndNil(CurrentIdentifierList);
|
FreeAndNil(CurrentIdentifierList);
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user