mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-15 18:59:40 +01:00
codetools: implemented FindCodeContext for procedures
git-svn-id: trunk@9296 -
This commit is contained in:
parent
8bb640c7fd
commit
d15d5a84e9
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -64,12 +64,15 @@ components/codetools/examples/finddeclaration.lpi svneol=native#text/plain
|
|||||||
components/codetools/examples/finddeclaration.lpr svneol=native#text/plain
|
components/codetools/examples/finddeclaration.lpr svneol=native#text/plain
|
||||||
components/codetools/examples/fixfilenames.lpi svneol=native#text/plain
|
components/codetools/examples/fixfilenames.lpi svneol=native#text/plain
|
||||||
components/codetools/examples/fixfilenames.pas svneol=native#text/plain
|
components/codetools/examples/fixfilenames.pas svneol=native#text/plain
|
||||||
|
components/codetools/examples/getcontext.lpi svneol=native#text/plain
|
||||||
|
components/codetools/examples/getcontext.lpr svneol=native#text/plain
|
||||||
components/codetools/examples/methodjumping.lpi svneol=native#text/plain
|
components/codetools/examples/methodjumping.lpi svneol=native#text/plain
|
||||||
components/codetools/examples/methodjumping.pas svneol=native#text/plain
|
components/codetools/examples/methodjumping.pas svneol=native#text/plain
|
||||||
components/codetools/examples/scanexamples/BigLettersUnit.pas svneol=native#text/plain
|
components/codetools/examples/scanexamples/BigLettersUnit.pas svneol=native#text/plain
|
||||||
components/codetools/examples/scanexamples/brokenfilenames.pas svneol=native#text/plain
|
components/codetools/examples/scanexamples/brokenfilenames.pas svneol=native#text/plain
|
||||||
components/codetools/examples/scanexamples/brokenincfiles.inc svneol=native#text/plain
|
components/codetools/examples/scanexamples/brokenincfiles.inc svneol=native#text/plain
|
||||||
components/codetools/examples/scanexamples/empty.inc svneol=native#text/plain
|
components/codetools/examples/scanexamples/empty.inc svneol=native#text/plain
|
||||||
|
components/codetools/examples/scanexamples/getcontextexample.pas svneol=native#text/plain
|
||||||
components/codetools/examples/scanexamples/simpleunit1.pas svneol=native#text/plain
|
components/codetools/examples/scanexamples/simpleunit1.pas svneol=native#text/plain
|
||||||
components/codetools/examples/scanexamples/tgeneric2.pas svneol=native#text/plain
|
components/codetools/examples/scanexamples/tgeneric2.pas svneol=native#text/plain
|
||||||
components/codetools/expreval.pas svneol=native#text/pascal
|
components/codetools/expreval.pas svneol=native#text/pascal
|
||||||
|
|||||||
@ -2661,7 +2661,7 @@ var CleanCursorPos, Indent, insertPos: integer;
|
|||||||
Params.OnTopLvlIdentifierFound:=@OnTopLvlIdentifierFound;
|
Params.OnTopLvlIdentifierFound:=@OnTopLvlIdentifierFound;
|
||||||
Params.Flags:=[fdfSearchInParentNodes,fdfSearchInAncestors,
|
Params.Flags:=[fdfSearchInParentNodes,fdfSearchInAncestors,
|
||||||
fdfTopLvlResolving,fdfFindVariable];
|
fdfTopLvlResolving,fdfFindVariable];
|
||||||
if (not FindDeclarationOfIdentAtCursor(Params))
|
if (not FindDeclarationOfIdentAtParam(Params))
|
||||||
or (Params.NewNode.Desc<>ctnProperty) then begin
|
or (Params.NewNode.Desc<>ctnProperty) then begin
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DebugLn('FindEventTypeAtCursor not a property');
|
DebugLn('FindEventTypeAtCursor not a property');
|
||||||
|
|||||||
48
components/codetools/examples/getcontext.lpi
Normal file
48
components/codetools/examples/getcontext.lpi
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<PathDelim Value="/"/>
|
||||||
|
<Version Value="5"/>
|
||||||
|
<General>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<MainUnit Value="0"/>
|
||||||
|
<IconPath Value="./"/>
|
||||||
|
<TargetFileExt Value=""/>
|
||||||
|
</General>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
|
||||||
|
<ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<local>
|
||||||
|
<FormatVersion Value="1"/>
|
||||||
|
<LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
|
||||||
|
</local>
|
||||||
|
</RunParams>
|
||||||
|
<Units Count="2">
|
||||||
|
<Unit0>
|
||||||
|
<Filename Value="getcontext.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="GetContext"/>
|
||||||
|
</Unit0>
|
||||||
|
<Unit1>
|
||||||
|
<Filename Value="scanexamples/getcontextexample.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="GetContextExample"/>
|
||||||
|
</Unit1>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="5"/>
|
||||||
|
<SearchPaths>
|
||||||
|
<OtherUnitFiles Value="$(LazarusDir)/components/codetools/units/$(TargetCPU)-$(TargetOS)/;scanexamples/"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<CodeGeneration>
|
||||||
|
<Generate Value="Faster"/>
|
||||||
|
</CodeGeneration>
|
||||||
|
<Other>
|
||||||
|
<CompilerPath Value="$(CompPath)"/>
|
||||||
|
</Other>
|
||||||
|
</CompilerOptions>
|
||||||
|
</CONFIG>
|
||||||
68
components/codetools/examples/getcontext.lpr
Normal file
68
components/codetools/examples/getcontext.lpr
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
program GetContext;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, CodeCache, CodeToolManager, DefineTemplates,
|
||||||
|
CodeToolsConfig, GetContextExample, IdentCompletionTool, FindDeclarationTool;
|
||||||
|
|
||||||
|
const
|
||||||
|
ConfigFilename = 'codetools.config';
|
||||||
|
var
|
||||||
|
Options: TCodeToolsOptions;
|
||||||
|
Code: TCodeBuffer;
|
||||||
|
CodeContexts: TCodeContextInfo;
|
||||||
|
i: Integer;
|
||||||
|
ExprType: TExpressionType;
|
||||||
|
begin
|
||||||
|
// setup the Options
|
||||||
|
Options:=TCodeToolsOptions.Create;
|
||||||
|
|
||||||
|
// To not parse the FPC sources every time, the options are saved to a file.
|
||||||
|
if FileExists(ConfigFilename) then
|
||||||
|
Options.LoadFromFile(ConfigFilename);
|
||||||
|
|
||||||
|
// setup your paths
|
||||||
|
Options.FPCPath:='/usr/bin/ppc386';
|
||||||
|
Options.FPCSrcDir:=ExpandFileName('~/freepascal/fpc');
|
||||||
|
Options.LazarusSrcDir:=ExpandFileName('~/pascal/lazarus');
|
||||||
|
|
||||||
|
// optional: ProjectDir and TestPascalFile exists only to easily test some
|
||||||
|
// things.
|
||||||
|
Options.ProjectDir:=GetCurrentDir+'/scanexamples/';
|
||||||
|
Options.TestPascalFile:=Options.ProjectDir+'getcontextexample.pas';
|
||||||
|
|
||||||
|
// init the codetools
|
||||||
|
if not Options.UnitLinkListValid then
|
||||||
|
writeln('Scanning FPC sources may take a while ...');
|
||||||
|
CodeToolBoss.Init(Options);
|
||||||
|
|
||||||
|
// save the options and the FPC unit links results.
|
||||||
|
Options.SaveToFile(ConfigFilename);
|
||||||
|
|
||||||
|
// Example: find declaration of 'TObject'
|
||||||
|
|
||||||
|
// Step 1: load the file
|
||||||
|
Code:=CodeToolBoss.LoadFile(Options.TestPascalFile,false,false);
|
||||||
|
if Code=nil then
|
||||||
|
raise Exception.Create('loading failed '+Options.TestPascalFile);
|
||||||
|
|
||||||
|
// Step 2: find context
|
||||||
|
if CodeToolBoss.FindCodeContext(Code,7,14,CodeContexts) then
|
||||||
|
begin
|
||||||
|
writeln('Contexts found: Count=',CodeContexts.Count);
|
||||||
|
for i:=0 to CodeContexts.Count-1 do begin
|
||||||
|
ExprType:=CodeContexts[i];
|
||||||
|
write('i=',i,' ',ExprTypeToString(ExprType));
|
||||||
|
if ExprType.Context.Node<>nil then
|
||||||
|
write(' ',ExprType.Context.Tool.ExtractNode(ExprType.Context.Node,[]));
|
||||||
|
writeln;
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
writeln('Contexts not found: ',CodeToolBoss.ErrorMessage);
|
||||||
|
end;
|
||||||
|
CodeContexts.Free;
|
||||||
|
|
||||||
|
Options.Free;
|
||||||
|
end.
|
||||||
|
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
unit GetContextExample;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
procedure CallOverloadedProc;
|
||||||
|
begin
|
||||||
|
Pos('','');
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
||||||
@ -366,7 +366,7 @@ var
|
|||||||
{$IFDEF CTDebug}
|
{$IFDEF CTDebug}
|
||||||
DebugLn('AddVariableAtCursor Searching ',GetIdentifier(Params.Identifier));
|
DebugLn('AddVariableAtCursor Searching ',GetIdentifier(Params.Identifier));
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
if not FindDeclarationOfIdentAtCursor(Params) then begin
|
if not FindDeclarationOfIdentAtParam(Params) then begin
|
||||||
{$IFDEF CTDebug}
|
{$IFDEF CTDebug}
|
||||||
DebugLn('AddVariableAtCursor B not found');
|
DebugLn('AddVariableAtCursor B not found');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|||||||
@ -496,23 +496,6 @@ const
|
|||||||
AllFindSmartFlags = [fsfIncludeDirective];
|
AllFindSmartFlags = [fsfIncludeDirective];
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
{ TCodeContextInfo }
|
|
||||||
|
|
||||||
TCodeContextInfo = class
|
|
||||||
private
|
|
||||||
FItems: PExpressionType;
|
|
||||||
FCount: integer;
|
|
||||||
function GetItems(Index: integer): TExpressionType;
|
|
||||||
public
|
|
||||||
constructor Create;
|
|
||||||
destructor Destroy; override;
|
|
||||||
function Count: integer;
|
|
||||||
property Items[Index: integer]: TExpressionType read GetItems; default;
|
|
||||||
function Add(const Context: TExpressionType): integer;
|
|
||||||
procedure Clear;
|
|
||||||
end;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
ECodeToolUnitNotFound = class(ECodeToolFileNotFound)
|
ECodeToolUnitNotFound = class(ECodeToolFileNotFound)
|
||||||
end;
|
end;
|
||||||
@ -617,7 +600,7 @@ type
|
|||||||
protected
|
protected
|
||||||
function CheckSrcIdentifier(Params: TFindDeclarationParams;
|
function CheckSrcIdentifier(Params: TFindDeclarationParams;
|
||||||
const FoundContext: TFindContext): TIdentifierFoundResult;
|
const FoundContext: TFindContext): TIdentifierFoundResult;
|
||||||
function FindDeclarationOfIdentAtCursor(
|
function FindDeclarationOfIdentAtParam(
|
||||||
Params: TFindDeclarationParams): boolean;
|
Params: TFindDeclarationParams): boolean;
|
||||||
function IdentifierIsDefined(IdentAtom: TAtomPosition;
|
function IdentifierIsDefined(IdentAtom: TAtomPosition;
|
||||||
ContextNode: TCodeTreeNode; Params: TFindDeclarationParams): boolean;
|
ContextNode: TCodeTreeNode; Params: TFindDeclarationParams): boolean;
|
||||||
@ -729,8 +712,6 @@ type
|
|||||||
|
|
||||||
function CleanPosIsDeclarationIdentifier(CleanPos: integer;
|
function CleanPosIsDeclarationIdentifier(CleanPos: integer;
|
||||||
Node: TCodeTreeNode): boolean;
|
Node: TCodeTreeNode): boolean;
|
||||||
function FindCodeContext(const CursorPos: TCodeXYPosition;
|
|
||||||
out CodeContexts: TCodeContextInfo): boolean;
|
|
||||||
|
|
||||||
function JumpToNode(ANode: TCodeTreeNode;
|
function JumpToNode(ANode: TCodeTreeNode;
|
||||||
var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
||||||
@ -1289,7 +1270,7 @@ begin
|
|||||||
fdfTopLvlResolving,fdfSearchInAncestors];
|
fdfTopLvlResolving,fdfSearchInAncestors];
|
||||||
if not DirectSearch then begin
|
if not DirectSearch then begin
|
||||||
// ToDo: DirtySrc
|
// ToDo: DirtySrc
|
||||||
Result:=FindDeclarationOfIdentAtCursor(Params);
|
Result:=FindDeclarationOfIdentAtParam(Params);
|
||||||
end else begin
|
end else begin
|
||||||
Include(Params.Flags,fdfIgnoreCurContextNode);
|
Include(Params.Flags,fdfIgnoreCurContextNode);
|
||||||
if SearchForward then
|
if SearchForward then
|
||||||
@ -1881,7 +1862,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFindDeclarationTool.FindDeclarationOfIdentAtCursor(
|
function TFindDeclarationTool.FindDeclarationOfIdentAtParam(
|
||||||
Params: TFindDeclarationParams): boolean;
|
Params: TFindDeclarationParams): boolean;
|
||||||
{ searches an identifier in clean code, parses code in front and after the
|
{ searches an identifier in clean code, parses code in front and after the
|
||||||
identifier
|
identifier
|
||||||
@ -1902,7 +1883,7 @@ var
|
|||||||
ExprType: TExpressionType;
|
ExprType: TExpressionType;
|
||||||
begin
|
begin
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DebugLn('[TFindDeclarationTool.FindDeclarationOfIdentAtCursor] Identifier=',
|
DebugLn('[TFindDeclarationTool.FindDeclarationOfIdentAtParam] Identifier=',
|
||||||
'"',GetIdentifier(Params.Identifier),'"',
|
'"',GetIdentifier(Params.Identifier),'"',
|
||||||
' ContextNode=',NodeDescriptionAsString(Params.ContextNode.Desc),
|
' ContextNode=',NodeDescriptionAsString(Params.ContextNode.Desc),
|
||||||
' "',copy(Src,Params.ContextNode.StartPos,20),'"');
|
' "',copy(Src,Params.ContextNode.StartPos,20),'"');
|
||||||
@ -1927,7 +1908,7 @@ begin
|
|||||||
Params.SetResult(CleanFindContext);
|
Params.SetResult(CleanFindContext);
|
||||||
end;
|
end;
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DbgOut('[TFindDeclarationTool.FindDeclarationOfIdentAtCursor] Ident=',
|
DbgOut('[TFindDeclarationTool.FindDeclarationOfIdentAtParam] Ident=',
|
||||||
'"',GetIdentifier(Params.Identifier),'" ');
|
'"',GetIdentifier(Params.Identifier),'" ');
|
||||||
if Params.NewNode<>nil then
|
if Params.NewNode<>nil then
|
||||||
DebugLn('Node=',Params.NewNode.DescAsString,' ',Params.NewCodeTool.MainFilename)
|
DebugLn('Node=',Params.NewNode.DescAsString,' ',Params.NewCodeTool.MainFilename)
|
||||||
@ -3279,7 +3260,7 @@ var
|
|||||||
if fdfSearchForward in Params.Flags then
|
if fdfSearchForward in Params.Flags then
|
||||||
Found:=FindIdentifierInContext(Params)
|
Found:=FindIdentifierInContext(Params)
|
||||||
else
|
else
|
||||||
Found:=FindDeclarationOfIdentAtCursor(Params);
|
Found:=FindDeclarationOfIdentAtParam(Params);
|
||||||
except
|
except
|
||||||
on E: ECodeToolError do
|
on E: ECodeToolError do
|
||||||
if not IsComment then raise;
|
if not IsComment then raise;
|
||||||
@ -3590,100 +3571,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TFindDeclarationTool.FindCodeContext(const CursorPos: TCodeXYPosition;
|
|
||||||
out CodeContexts: TCodeContextInfo): boolean;
|
|
||||||
var
|
|
||||||
CleanCursorPos: integer;
|
|
||||||
CursorNode: TCodeTreeNode;
|
|
||||||
Params: TFindDeclarationParams;
|
|
||||||
|
|
||||||
procedure AddContext(Tool: TFindDeclarationTool; Node: TCodeTreeNode);
|
|
||||||
begin
|
|
||||||
if CodeContexts=nil then
|
|
||||||
CodeContexts:=TCodeContextInfo.Create;
|
|
||||||
CodeContexts.Add(CreateExpressionType(xtContext,xtNone,
|
|
||||||
CreateFindContext(Tool,Node)));
|
|
||||||
//DebugLn('AddContext ',node.DescAsString,' ',copy(Src,Node.StartPos,Node.EndPos-Node.StartPos));
|
|
||||||
end;
|
|
||||||
|
|
||||||
function CheckContextIsParameter(var Ok: boolean): boolean;
|
|
||||||
// returns true, on error or context is parameter
|
|
||||||
// returns false, if no error and context is not parameter
|
|
||||||
var
|
|
||||||
VarNameAtom, ProcNameAtom: TAtomPosition;
|
|
||||||
ParameterIndex: integer;
|
|
||||||
ParameterNode: TCodeTreeNode;
|
|
||||||
begin
|
|
||||||
Result:=false;
|
|
||||||
//DebugLn('CheckContextIsParameter ');
|
|
||||||
if not CheckParameterSyntax(CursorNode, CleanCursorPos,
|
|
||||||
VarNameAtom, ProcNameAtom, ParameterIndex) then exit;
|
|
||||||
if VarNameAtom.StartPos<1 then exit;
|
|
||||||
// it is a parameter
|
|
||||||
Result:=true;
|
|
||||||
ok:=true;
|
|
||||||
// find declaration of parameter list
|
|
||||||
Params.ContextNode:=CursorNode;
|
|
||||||
Params.SetIdentifier(Self,@Src[ProcNameAtom.StartPos],@CheckSrcIdentifier);
|
|
||||||
Params.Flags:=fdfGlobals+[fdfSearchInParentNodes,fdfSearchInAncestors,
|
|
||||||
fdfFindVariable,fdfIgnoreCurContextNode];
|
|
||||||
//DebugLn('CheckContextIsParameter searching procedure ...');
|
|
||||||
if not FindIdentifierInContext(Params) then exit;
|
|
||||||
if Params.NewNode<>nil then begin
|
|
||||||
//DebugLn('CheckContextIsParameter searching parameter node ...');
|
|
||||||
ParameterNode:=Params.NewCodeTool.FindNthParameterNode(Params.NewNode,
|
|
||||||
ParameterIndex);
|
|
||||||
if ParameterNode<>nil then begin
|
|
||||||
//DebugLn('CheckContextIsParameter adding parameter node to CodeContexts');
|
|
||||||
AddContext(Params.NewCodeTool,ParameterNode);
|
|
||||||
|
|
||||||
end;
|
|
||||||
//DebugLn(' CompleteLocalVariableAsParameter Dont know: ',Params.NewNode.DescAsString);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
|
||||||
CodeContexts:=nil;
|
|
||||||
Result:=false;
|
|
||||||
ActivateGlobalWriteLock;
|
|
||||||
Params:=TFindDeclarationParams.Create;
|
|
||||||
try
|
|
||||||
// build code tree
|
|
||||||
{$IFDEF CTDEBUG}
|
|
||||||
DebugLn('TFindDeclarationTool.FindCodeContext A CursorPos=X',dbgs(CursorPos.X),',Y',dbgs(CursorPos.Y));
|
|
||||||
{$ENDIF}
|
|
||||||
if DirtySrc<>nil then DirtySrc.Clear;
|
|
||||||
BuildTreeAndGetCleanPos(trTillCursor,CursorPos,CleanCursorPos,
|
|
||||||
[{$IFNDEF DisableIgnoreErrorAfter}btSetIgnoreErrorPos,{$ENDIF}
|
|
||||||
btLoadDirtySource,btCursorPosOutAllowed]);
|
|
||||||
{$IFDEF CTDEBUG}
|
|
||||||
DebugLn('TFindDeclarationTool.FindCodeContext C CleanCursorPos=',dbgs(CleanCursorPos));
|
|
||||||
{$ENDIF}
|
|
||||||
// find CodeTreeNode at cursor
|
|
||||||
if (Tree.Root<>nil) and (Tree.Root.StartPos<=CleanCursorPos) then begin
|
|
||||||
CursorNode:=BuildSubTreeAndFindDeepestNodeAtPos(Tree.Root,CleanCursorPos,
|
|
||||||
true);
|
|
||||||
end else begin
|
|
||||||
CursorNode:=nil;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if CursorNode<>nil then begin
|
|
||||||
if CheckContextIsParameter(Result) then exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if CodeContexts=nil then begin
|
|
||||||
// create default
|
|
||||||
AddContext(Self,CursorNode);
|
|
||||||
end;
|
|
||||||
|
|
||||||
Result:=true;
|
|
||||||
finally
|
|
||||||
Params.Free;
|
|
||||||
DeactivateGlobalWriteLock;
|
|
||||||
end;
|
|
||||||
Result:=false;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TFindDeclarationTool.JumpToNode(ANode: TCodeTreeNode;
|
function TFindDeclarationTool.JumpToNode(ANode: TCodeTreeNode;
|
||||||
var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
||||||
IgnoreJumpCentered: boolean): boolean;
|
IgnoreJumpCentered: boolean): boolean;
|
||||||
@ -7879,42 +7766,5 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TCodeContextInfo }
|
|
||||||
|
|
||||||
function TCodeContextInfo.GetItems(Index: integer): TExpressionType;
|
|
||||||
begin
|
|
||||||
Result:=FItems[Index];
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TCodeContextInfo.Create;
|
|
||||||
begin
|
|
||||||
|
|
||||||
end;
|
|
||||||
|
|
||||||
destructor TCodeContextInfo.Destroy;
|
|
||||||
begin
|
|
||||||
Clear;
|
|
||||||
inherited Destroy;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCodeContextInfo.Count: integer;
|
|
||||||
begin
|
|
||||||
Result:=FCount;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCodeContextInfo.Add(const Context: TExpressionType): integer;
|
|
||||||
begin
|
|
||||||
inc(FCount);
|
|
||||||
Result:=Count;
|
|
||||||
ReAllocMem(FItems,SizeOf(TExpressionType)*FCount);
|
|
||||||
FItems[FCount-1]:=Context;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TCodeContextInfo.Clear;
|
|
||||||
begin
|
|
||||||
FCount:=0;
|
|
||||||
ReAllocMem(FItems,0);
|
|
||||||
end;
|
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|||||||
@ -209,6 +209,32 @@ type
|
|||||||
property Capacity: integer read FCapacity write SetCapacity;
|
property Capacity: integer read FCapacity write SetCapacity;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
{ TCodeContextInfo }
|
||||||
|
|
||||||
|
TCodeContextInfo = class
|
||||||
|
private
|
||||||
|
FEndPos: integer;
|
||||||
|
FItems: PExpressionType;
|
||||||
|
FCount: integer;
|
||||||
|
FParameterIndex: integer;
|
||||||
|
FProcName: string;
|
||||||
|
FStartPos: integer;
|
||||||
|
function GetItems(Index: integer): TExpressionType;
|
||||||
|
public
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
function Count: integer;
|
||||||
|
property Items[Index: integer]: TExpressionType read GetItems; default;
|
||||||
|
function Add(const Context: TExpressionType): integer;
|
||||||
|
procedure Clear;
|
||||||
|
property ParameterIndex: integer read FParameterIndex write FParameterIndex;// 1 based
|
||||||
|
property ProcName: string read FProcName write FProcName;
|
||||||
|
property StartPos: integer read FStartPos write FStartPos;// context is valid from StartPos to EndPos
|
||||||
|
property EndPos: integer read FEndPos write FEndPos;
|
||||||
|
end;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// TIdentCompletionTool
|
// TIdentCompletionTool
|
||||||
|
|
||||||
@ -221,6 +247,7 @@ type
|
|||||||
// property names in source)
|
// property names in source)
|
||||||
protected
|
protected
|
||||||
CurrentIdentifierList: TIdentifierList;
|
CurrentIdentifierList: TIdentifierList;
|
||||||
|
CurrentContexts: TCodeContextInfo;
|
||||||
function CollectAllIdentifiers(Params: TFindDeclarationParams;
|
function CollectAllIdentifiers(Params: TFindDeclarationParams;
|
||||||
const FoundContext: TFindContext): TIdentifierFoundResult;
|
const FoundContext: TFindContext): TIdentifierFoundResult;
|
||||||
procedure GatherPredefinedIdentifiers(CleanPos: integer;
|
procedure GatherPredefinedIdentifiers(CleanPos: integer;
|
||||||
@ -230,10 +257,25 @@ type
|
|||||||
procedure GatherUnitnames(CleanPos: integer;
|
procedure GatherUnitnames(CleanPos: integer;
|
||||||
const Context: TFindContext; BeautifyCodeOptions: TBeautifyCodeOptions);
|
const Context: TFindContext; BeautifyCodeOptions: TBeautifyCodeOptions);
|
||||||
procedure GatherSourceNames(const Context: TFindContext);
|
procedure GatherSourceNames(const Context: TFindContext);
|
||||||
|
procedure InitCollectIdentifiers(const CursorPos: TCodeXYPosition;
|
||||||
|
var IdentifierList: TIdentifierList);
|
||||||
|
procedure ParseSourceTillCollectionStart(const CursorPos: TCodeXYPosition;
|
||||||
|
out CleanCursorPos: integer; out CursorNode: TCodeTreeNode;
|
||||||
|
out IdentStartPos, IdentEndPos: integer);
|
||||||
|
procedure FindCollectionContext(Params: TFindDeclarationParams;
|
||||||
|
IdentStartPos: integer; CursorNode: TCodeTreeNode;
|
||||||
|
out GatherContext: TFindContext; out ContextExprStartPos: LongInt;
|
||||||
|
out StartInSubContext: Boolean);
|
||||||
|
function CollectAllContexts(Params: TFindDeclarationParams;
|
||||||
|
const FoundContext: TFindContext): TIdentifierFoundResult;
|
||||||
|
procedure AddCollectionContext(Tool: TFindDeclarationTool;
|
||||||
|
Node: TCodeTreeNode);
|
||||||
public
|
public
|
||||||
function GatherIdentifiers(const CursorPos: TCodeXYPosition;
|
function GatherIdentifiers(const CursorPos: TCodeXYPosition;
|
||||||
var IdentifierList: TIdentifierList;
|
var IdentifierList: TIdentifierList;
|
||||||
BeautifyCodeOptions: TBeautifyCodeOptions): boolean;
|
BeautifyCodeOptions: TBeautifyCodeOptions): boolean;
|
||||||
|
function FindCodeContext(const CursorPos: TCodeXYPosition;
|
||||||
|
out CodeContexts: TCodeContextInfo): boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -1087,9 +1129,49 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TIdentCompletionTool.GatherIdentifiers(
|
procedure TIdentCompletionTool.InitCollectIdentifiers(
|
||||||
const CursorPos: TCodeXYPosition; var IdentifierList: TIdentifierList;
|
const CursorPos: TCodeXYPosition; var IdentifierList: TIdentifierList);
|
||||||
BeautifyCodeOptions: TBeautifyCodeOptions): boolean;
|
begin
|
||||||
|
if IdentifierList=nil then IdentifierList:=TIdentifierList.Create;
|
||||||
|
CurrentIdentifierList:=IdentifierList;
|
||||||
|
CurrentIdentifierList.Clear;
|
||||||
|
LastGatheredIdentParent:=nil;
|
||||||
|
LastGatheredIdentLevel:=0;
|
||||||
|
CurrentIdentifierList.StartContextPos:=CursorPos;
|
||||||
|
CurrentIdentifierList.StartContext.Tool:=Self;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIdentCompletionTool.ParseSourceTillCollectionStart(
|
||||||
|
const CursorPos: TCodeXYPosition; out CleanCursorPos: integer;
|
||||||
|
out CursorNode: TCodeTreeNode; out IdentStartPos, IdentEndPos: integer);
|
||||||
|
begin
|
||||||
|
CleanCursorPos:=0;
|
||||||
|
CursorNode:=nil;
|
||||||
|
IdentStartPos:=0;
|
||||||
|
IdentEndPos:=0;
|
||||||
|
|
||||||
|
// build code tree
|
||||||
|
{$IFDEF CTDEBUG}
|
||||||
|
DebugLn('TIdentCompletionTool.GatherIdentifiers A CursorPos=',dbgs(CursorPos.X),',',dbgs(CursorPos.Y));
|
||||||
|
{$ENDIF}
|
||||||
|
BuildTreeAndGetCleanPos(trTillCursor,CursorPos,CleanCursorPos,
|
||||||
|
[{$IFNDEF DisableIgnoreErrorAfter}btSetIgnoreErrorPos{$ENDIF}]);
|
||||||
|
|
||||||
|
// find node at position
|
||||||
|
CursorNode:=FindDeepestExpandedNodeAtPos(CleanCursorPos,true);
|
||||||
|
if CurrentIdentifierList<>nil then
|
||||||
|
CurrentIdentifierList.StartContext.Node:=CursorNode;
|
||||||
|
|
||||||
|
// get identifier position
|
||||||
|
GetIdentStartEndAtPosition(Src,CleanCursorPos,IdentStartPos,IdentEndPos);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIdentCompletionTool.FindCollectionContext(
|
||||||
|
Params: TFindDeclarationParams; IdentStartPos: integer;
|
||||||
|
CursorNode: TCodeTreeNode;
|
||||||
|
out GatherContext: TFindContext;
|
||||||
|
out ContextExprStartPos: LongInt;
|
||||||
|
out StartInSubContext: Boolean);
|
||||||
|
|
||||||
function GetContextExprStartPos(IdentStartPos: integer;
|
function GetContextExprStartPos(IdentStartPos: integer;
|
||||||
ContextNode: TCodeTreeNode): integer;
|
ContextNode: TCodeTreeNode): integer;
|
||||||
@ -1111,67 +1193,14 @@ function TIdentCompletionTool.GatherIdentifiers(
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
CleanCursorPos, IdentStartPos, IdentEndPos: integer;
|
|
||||||
CursorNode: TCodeTreeNode;
|
|
||||||
Params: TFindDeclarationParams;
|
|
||||||
GatherContext: TFindContext;
|
|
||||||
ExprType: TExpressionType;
|
ExprType: TExpressionType;
|
||||||
ContextExprStartPos: Integer;
|
|
||||||
StartInSubContext: Boolean;
|
|
||||||
StartPosOfVariable: LongInt;
|
|
||||||
begin
|
begin
|
||||||
Result:=false;
|
|
||||||
if IdentifierList=nil then IdentifierList:=TIdentifierList.Create;
|
|
||||||
CurrentIdentifierList:=IdentifierList;
|
|
||||||
CurrentIdentifierList.Clear;
|
|
||||||
LastGatheredIdentParent:=nil;
|
|
||||||
LastGatheredIdentLevel:=0;
|
|
||||||
CurrentIdentifierList.StartContextPos:=CursorPos;
|
|
||||||
CurrentIdentifierList.StartContext.Tool:=Self;
|
|
||||||
|
|
||||||
ActivateGlobalWriteLock;
|
|
||||||
Params:=TFindDeclarationParams.Create;
|
|
||||||
try
|
|
||||||
// build code tree
|
|
||||||
{$IFDEF CTDEBUG}
|
|
||||||
DebugLn('TIdentCompletionTool.GatherIdentifiers A CursorPos=',dbgs(CursorPos.X),',',dbgs(CursorPos.Y));
|
|
||||||
{$ENDIF}
|
|
||||||
BuildTreeAndGetCleanPos(trTillCursor,CursorPos,CleanCursorPos,
|
|
||||||
[{$IFNDEF DisableIgnoreErrorAfter}btSetIgnoreErrorPos{$ENDIF}]);
|
|
||||||
|
|
||||||
// find node at position
|
|
||||||
CursorNode:=FindDeepestExpandedNodeAtPos(CleanCursorPos,true);
|
|
||||||
CurrentIdentifierList.StartContext.Node:=CursorNode;
|
|
||||||
|
|
||||||
// find class and ancestors if existing (needed for protected identifiers)
|
|
||||||
FindContextClassAndAncestors(CursorPos,ClassAndAncestors);
|
|
||||||
|
|
||||||
// get identifier position
|
|
||||||
GetIdentStartEndAtPosition(Src,CleanCursorPos,IdentStartPos,IdentEndPos);
|
|
||||||
|
|
||||||
// find context
|
|
||||||
{$IFDEF CTDEBUG}
|
|
||||||
DebugLn('TIdentCompletionTool.GatherIdentifiers B',
|
|
||||||
' CleanCursorPos=',dbgs(CleanCursorPos),
|
|
||||||
' IdentStartPos=',dbgs(IdentStartPos),' IdentEndPos=',dbgs(IdentEndPos),
|
|
||||||
' Ident=',copy(Src,IdentStartPos,IdentEndPos-IdentStartPos));
|
|
||||||
{$ENDIF}
|
|
||||||
GatherContext:=CreateFindContext(Self,CursorNode);
|
GatherContext:=CreateFindContext(Self,CursorNode);
|
||||||
if CursorNode.Desc=ctnUsesSection then begin
|
|
||||||
GatherUnitNames(IdentStartPos,GatherContext,BeautifyCodeOptions);
|
|
||||||
end else if CursorNode.Desc in AllSourceTypes then begin
|
|
||||||
GatherSourceNames(GatherContext);
|
|
||||||
end else begin
|
|
||||||
ContextExprStartPos:=GetContextExprStartPos(IdentStartPos,CursorNode);
|
ContextExprStartPos:=GetContextExprStartPos(IdentStartPos,CursorNode);
|
||||||
if GatherContext.Node.Desc=ctnWithVariable then
|
if GatherContext.Node.Desc=ctnWithVariable then
|
||||||
GatherContext.Node:=GatherContext.Node.Parent;
|
GatherContext.Node:=GatherContext.Node.Parent;
|
||||||
|
|
||||||
{$IFDEF CTDEBUG}
|
|
||||||
DebugLn('TIdentCompletionTool.GatherIdentifiers C',
|
|
||||||
' ContextExprStartPos=',dbgs(ContextExprStartPos),
|
|
||||||
' Expr=',StringToPascalConst(copy(Src,ContextExprStartPos,
|
|
||||||
IdentStartPos-ContextExprStartPos)));
|
|
||||||
{$ENDIF}
|
|
||||||
StartInSubContext:=false;
|
StartInSubContext:=false;
|
||||||
if ContextExprStartPos<IdentStartPos then begin
|
if ContextExprStartPos<IdentStartPos then begin
|
||||||
MoveCursorToCleanPos(IdentStartPos);
|
MoveCursorToCleanPos(IdentStartPos);
|
||||||
@ -1186,6 +1215,78 @@ begin
|
|||||||
StartInSubContext:=true;
|
StartInSubContext:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TIdentCompletionTool.CollectAllContexts(
|
||||||
|
Params: TFindDeclarationParams; const FoundContext: TFindContext
|
||||||
|
): TIdentifierFoundResult;
|
||||||
|
begin
|
||||||
|
Result:=ifrProceedSearch;
|
||||||
|
if FoundContext.Node=nil then exit;
|
||||||
|
case FoundContext.Node.Desc of
|
||||||
|
ctnProcedure:
|
||||||
|
begin
|
||||||
|
if (CurrentContexts.ProcName='') then exit;
|
||||||
|
FoundContext.Tool.MoveCursorToProcName(FoundContext.Node,true);
|
||||||
|
if not FoundContext.Tool.CompareSrcIdentifier(
|
||||||
|
FoundContext.Tool.CurPos.StartPos,
|
||||||
|
CurrentContexts.ProcName) then exit;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
AddCollectionContext(FoundContext.Tool,FoundContext.Node);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIdentCompletionTool.AddCollectionContext(Tool: TFindDeclarationTool;
|
||||||
|
Node: TCodeTreeNode);
|
||||||
|
begin
|
||||||
|
if CurrentContexts=nil then
|
||||||
|
CurrentContexts:=TCodeContextInfo.Create;
|
||||||
|
CurrentContexts.Add(CreateExpressionType(xtContext,xtNone,
|
||||||
|
CreateFindContext(Tool,Node)));
|
||||||
|
//DebugLn('TIdentCompletionTool.AddCollectionContext ',Node.DescAsString,' ',ExtractNode(Node,[]));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TIdentCompletionTool.GatherIdentifiers(
|
||||||
|
const CursorPos: TCodeXYPosition; var IdentifierList: TIdentifierList;
|
||||||
|
BeautifyCodeOptions: TBeautifyCodeOptions): boolean;
|
||||||
|
var
|
||||||
|
CleanCursorPos, IdentStartPos, IdentEndPos: integer;
|
||||||
|
CursorNode: TCodeTreeNode;
|
||||||
|
Params: TFindDeclarationParams;
|
||||||
|
GatherContext: TFindContext;
|
||||||
|
ContextExprStartPos: Integer;
|
||||||
|
StartInSubContext: Boolean;
|
||||||
|
StartPosOfVariable: LongInt;
|
||||||
|
begin
|
||||||
|
Result:=false;
|
||||||
|
|
||||||
|
ActivateGlobalWriteLock;
|
||||||
|
Params:=TFindDeclarationParams.Create;
|
||||||
|
try
|
||||||
|
InitCollectIdentifiers(CursorPos,IdentifierList);
|
||||||
|
ParseSourceTillCollectionStart(CursorPos,CleanCursorPos,CursorNode,
|
||||||
|
IdentStartPos,IdentEndPos);
|
||||||
|
|
||||||
|
// find context
|
||||||
|
{$IFDEF CTDEBUG}
|
||||||
|
DebugLn('TIdentCompletionTool.GatherIdentifiers B',
|
||||||
|
' CleanCursorPos=',dbgs(CleanCursorPos),
|
||||||
|
' IdentStartPos=',dbgs(IdentStartPos),' IdentEndPos=',dbgs(IdentEndPos),
|
||||||
|
' Ident=',copy(Src,IdentStartPos,IdentEndPos-IdentStartPos));
|
||||||
|
{$ENDIF}
|
||||||
|
GatherContext:=CreateFindContext(Self,CursorNode);
|
||||||
|
if CursorNode.Desc=ctnUsesSection then begin
|
||||||
|
GatherUnitNames(IdentStartPos,GatherContext,BeautifyCodeOptions);
|
||||||
|
end else if CursorNode.Desc in AllSourceTypes then begin
|
||||||
|
GatherSourceNames(GatherContext);
|
||||||
|
end else begin
|
||||||
|
// find class and ancestors if existing (needed for protected identifiers)
|
||||||
|
FindContextClassAndAncestors(CursorPos,ClassAndAncestors);
|
||||||
|
|
||||||
|
FindCollectionContext(Params,IdentStartPos,CursorNode,
|
||||||
|
GatherContext,ContextExprStartPos,StartInSubContext);
|
||||||
|
|
||||||
// search and gather identifiers in context
|
// search and gather identifiers in context
|
||||||
if (GatherContext.Tool<>nil) and (GatherContext.Node<>nil) then begin
|
if (GatherContext.Tool<>nil) and (GatherContext.Node<>nil) then begin
|
||||||
@ -1283,12 +1384,120 @@ begin
|
|||||||
Params.Free;
|
Params.Free;
|
||||||
ClearIgnoreErrorAfter;
|
ClearIgnoreErrorAfter;
|
||||||
DeactivateGlobalWriteLock;
|
DeactivateGlobalWriteLock;
|
||||||
|
CurrentIdentifierList:=nil;
|
||||||
end;
|
end;
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DebugLn('TIdentCompletionTool.GatherIdentifiers END');
|
DebugLn('TIdentCompletionTool.GatherIdentifiers END');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TIdentCompletionTool.FindCodeContext(const CursorPos: TCodeXYPosition;
|
||||||
|
out CodeContexts: TCodeContextInfo): boolean;
|
||||||
|
var
|
||||||
|
CleanCursorPos: integer;
|
||||||
|
CursorNode: TCodeTreeNode;
|
||||||
|
Params: TFindDeclarationParams;
|
||||||
|
|
||||||
|
function CheckContextIsParameter(var Ok: boolean): boolean;
|
||||||
|
// returns true, on error or context is parameter
|
||||||
|
// returns false, if no error and context is not parameter
|
||||||
|
var
|
||||||
|
VarNameAtom, ProcNameAtom: TAtomPosition;
|
||||||
|
ParameterIndex: integer;
|
||||||
|
GatherContext: TFindContext;
|
||||||
|
ContextExprStartPos: LongInt;
|
||||||
|
StartInSubContext: Boolean;
|
||||||
|
begin
|
||||||
|
Result:=false;
|
||||||
|
if (CursorNode.Desc<>ctnBeginBlock)
|
||||||
|
and (not CursorNode.HasParentOfType(ctnBeginBlock)) then exit;
|
||||||
|
//DebugLn('CheckContextIsParameter ');
|
||||||
|
if not CheckParameterSyntax(CursorNode, CleanCursorPos,
|
||||||
|
VarNameAtom, ProcNameAtom, ParameterIndex) then exit;
|
||||||
|
if VarNameAtom.StartPos<1 then exit;
|
||||||
|
//DebugLn('CheckContextIsParameter Variable=',GetAtom(VarNameAtom),' Proc=',GetAtom(ProcNameAtom),' ParameterIndex=',dbgs(ParameterIndex));
|
||||||
|
|
||||||
|
// it is a parameter -> save ParameterIndex
|
||||||
|
Result:=true;
|
||||||
|
if CurrentContexts=nil then
|
||||||
|
CurrentContexts:=TCodeContextInfo.Create;
|
||||||
|
CurrentContexts.ParameterIndex:=ParameterIndex+1;
|
||||||
|
CurrentContexts.ProcName:=GetAtom(ProcNameAtom);
|
||||||
|
MoveCursorToAtomPos(ProcNameAtom);
|
||||||
|
ReadNextAtom; // read opening bracket
|
||||||
|
CurrentContexts.StartPos:=CurPos.EndPos;
|
||||||
|
// read closing bracket
|
||||||
|
if ReadTilBracketClose(false) then
|
||||||
|
CurrentContexts.EndPos:=CurPos.StartPos
|
||||||
|
else
|
||||||
|
CurrentContexts.EndPos:=SrcLen+1;
|
||||||
|
|
||||||
|
FindCollectionContext(Params,ProcNameAtom.StartPos,CursorNode,
|
||||||
|
GatherContext,ContextExprStartPos,StartInSubContext);
|
||||||
|
|
||||||
|
// gather declarations of parameter lists
|
||||||
|
Params.ContextNode:=GatherContext.Node;
|
||||||
|
Params.SetIdentifier(Self,@Src[ProcNameAtom.StartPos],@CollectAllContexts);
|
||||||
|
Params.Flags:=[fdfSearchInAncestors,fdfCollect,fdfFindVariable];
|
||||||
|
if not StartInSubContext then
|
||||||
|
Include(Params.Flags,fdfSearchInParentNodes);
|
||||||
|
if Params.ContextNode.Desc in [ctnClass,ctnClassInterface] then
|
||||||
|
Exclude(Params.Flags,fdfSearchInParentNodes);
|
||||||
|
CurrentIdentifierList.Context:=GatherContext;
|
||||||
|
//DebugLn('CheckContextIsParameter searching procedure ...');
|
||||||
|
GatherContext.Tool.FindIdentifierInContext(Params);
|
||||||
|
//DebugLn('CheckContextIsParameter END');
|
||||||
|
Ok:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
IdentifierList: TIdentifierList;
|
||||||
|
IdentStartPos, IdentEndPos: integer;
|
||||||
|
begin
|
||||||
|
CodeContexts:=nil;
|
||||||
|
Result:=false;
|
||||||
|
|
||||||
|
IdentifierList:=nil;
|
||||||
|
CurrentContexts:=CodeContexts;
|
||||||
|
|
||||||
|
ActivateGlobalWriteLock;
|
||||||
|
Params:=TFindDeclarationParams.Create;
|
||||||
|
try
|
||||||
|
InitCollectIdentifiers(CursorPos,IdentifierList);
|
||||||
|
ParseSourceTillCollectionStart(CursorPos,CleanCursorPos,CursorNode,
|
||||||
|
IdentStartPos,IdentEndPos);
|
||||||
|
|
||||||
|
// find class and ancestors if existing (needed for protected identifiers)
|
||||||
|
FindContextClassAndAncestors(CursorPos,ClassAndAncestors);
|
||||||
|
|
||||||
|
if CursorNode<>nil then begin
|
||||||
|
if CheckContextIsParameter(Result) then exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if CodeContexts=nil then begin
|
||||||
|
// create default
|
||||||
|
AddCollectionContext(Self,CursorNode);
|
||||||
|
end;
|
||||||
|
|
||||||
|
Result:=true;
|
||||||
|
finally
|
||||||
|
if Result then begin
|
||||||
|
CodeContexts:=CurrentContexts;
|
||||||
|
CurrentContexts:=nil;
|
||||||
|
end else begin
|
||||||
|
FreeAndNil(CurrentContexts);
|
||||||
|
end;
|
||||||
|
FreeListOfPFindContext(ClassAndAncestors);
|
||||||
|
FreeAndNil(FoundPublicProperties);
|
||||||
|
Params.Free;
|
||||||
|
ClearIgnoreErrorAfter;
|
||||||
|
DeactivateGlobalWriteLock;
|
||||||
|
FreeAndNil(CurrentIdentifierList);
|
||||||
|
end;
|
||||||
|
Result:=false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TIdentifierListItem }
|
{ TIdentifierListItem }
|
||||||
|
|
||||||
function TIdentifierListItem.GetParamList: string;
|
function TIdentifierListItem.GetParamList: string;
|
||||||
@ -1553,6 +1762,43 @@ begin
|
|||||||
Result:=FItems.Count;
|
Result:=FItems.Count;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TCodeContextInfo }
|
||||||
|
|
||||||
|
function TCodeContextInfo.GetItems(Index: integer): TExpressionType;
|
||||||
|
begin
|
||||||
|
Result:=FItems[Index];
|
||||||
|
end;
|
||||||
|
|
||||||
|
constructor TCodeContextInfo.Create;
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TCodeContextInfo.Destroy;
|
||||||
|
begin
|
||||||
|
Clear;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCodeContextInfo.Count: integer;
|
||||||
|
begin
|
||||||
|
Result:=FCount;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCodeContextInfo.Add(const Context: TExpressionType): integer;
|
||||||
|
begin
|
||||||
|
inc(FCount);
|
||||||
|
Result:=Count;
|
||||||
|
ReAllocMem(FItems,SizeOf(TExpressionType)*FCount);
|
||||||
|
FItems[FCount-1]:=Context;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TCodeContextInfo.Clear;
|
||||||
|
begin
|
||||||
|
FCount:=0;
|
||||||
|
ReAllocMem(FItems,0);
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
IdentifierListItemMemManager:=TIdentifierListItemMemManager.Create;
|
IdentifierListItemMemManager:=TIdentifierListItemMemManager.Create;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user