mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-20 17:11:03 +01:00
ident completion: added special identifiers Self and Result
git-svn-id: trunk@3784 -
This commit is contained in:
parent
793dcc8be5
commit
cacafb6ba0
@ -79,6 +79,7 @@ type
|
|||||||
FParamList: string;
|
FParamList: string;
|
||||||
FParamListValid: boolean;
|
FParamListValid: boolean;
|
||||||
function GetParamList: string;
|
function GetParamList: string;
|
||||||
|
procedure SetParamList(const AValue: string);
|
||||||
public
|
public
|
||||||
Compatibility: TIdentifierCompatibility;
|
Compatibility: TIdentifierCompatibility;
|
||||||
HasChilds: boolean; // identifier can contain childs (class, record)
|
HasChilds: boolean; // identifier can contain childs (class, record)
|
||||||
@ -87,8 +88,10 @@ type
|
|||||||
Level: integer;
|
Level: integer;
|
||||||
Node: TCodeTreeNode;
|
Node: TCodeTreeNode;
|
||||||
Tool: TFindDeclarationTool;
|
Tool: TFindDeclarationTool;
|
||||||
|
DefaultDesc: TCodeTreeNodeDesc;
|
||||||
function AsString: string;
|
function AsString: string;
|
||||||
property ParamList: string read GetParamList;
|
function GetDesc: TCodeTreeNodeDesc;
|
||||||
|
property ParamList: string read GetParamList write SetParamList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TIdentifierListFlag = (ilfFilteredListNeedsUpdate);
|
TIdentifierListFlag = (ilfFilteredListNeedsUpdate);
|
||||||
@ -101,6 +104,7 @@ type
|
|||||||
FHistory: TIdentifierHistoryList;
|
FHistory: TIdentifierHistoryList;
|
||||||
FItems: TAVLTree; // tree of TIdentifierListItem (completely sorted)
|
FItems: TAVLTree; // tree of TIdentifierListItem (completely sorted)
|
||||||
FIdentView: TAVLTree; // tree of TIdentHistListItem sorted for identifiers
|
FIdentView: TAVLTree; // tree of TIdentHistListItem sorted for identifiers
|
||||||
|
FIdentSearchItem: TIdentifierListItem;
|
||||||
FPrefix: string;
|
FPrefix: string;
|
||||||
procedure SetHistory(const AValue: TIdentifierHistoryList);
|
procedure SetHistory(const AValue: TIdentifierHistoryList);
|
||||||
procedure UpdateFilteredList;
|
procedure UpdateFilteredList;
|
||||||
@ -113,6 +117,7 @@ type
|
|||||||
procedure Add(NewItem: TIdentifierListItem);
|
procedure Add(NewItem: TIdentifierListItem);
|
||||||
function Count: integer;
|
function Count: integer;
|
||||||
function GetFilteredCount: integer;
|
function GetFilteredCount: integer;
|
||||||
|
function HasIdentifier(Identifier: PChar; const ParamList: string): boolean;
|
||||||
public
|
public
|
||||||
property Prefix: string read FPrefix write SetPrefix;
|
property Prefix: string read FPrefix write SetPrefix;
|
||||||
property FilteredItems[Index: integer]: TIdentifierListItem
|
property FilteredItems[Index: integer]: TIdentifierListItem
|
||||||
@ -159,7 +164,10 @@ type
|
|||||||
CurrentIdentifierList: TIdentifierList;
|
CurrentIdentifierList: TIdentifierList;
|
||||||
function CollectAllIdentifiers(Params: TFindDeclarationParams;
|
function CollectAllIdentifiers(Params: TFindDeclarationParams;
|
||||||
const FoundContext: TFindContext): TIdentifierFoundResult;
|
const FoundContext: TFindContext): TIdentifierFoundResult;
|
||||||
procedure GatherPredefinedIdentifiers;
|
procedure GatherPredefinedIdentifiers(CleanPos: integer;
|
||||||
|
const Context: TFindContext);
|
||||||
|
procedure GatherUsefulIdentifiers(CleanPos: integer;
|
||||||
|
const Context: TFindContext);
|
||||||
public
|
public
|
||||||
function GatherIdentifiers(const CursorPos: TCodeXYPosition;
|
function GatherIdentifiers(const CursorPos: TCodeXYPosition;
|
||||||
var IdentifierList: TIdentifierList): boolean;
|
var IdentifierList: TIdentifierList): boolean;
|
||||||
@ -320,6 +328,7 @@ begin
|
|||||||
FFlags:=[ilfFilteredListNeedsUpdate];
|
FFlags:=[ilfFilteredListNeedsUpdate];
|
||||||
FItems:=TAVLTree.Create(@CompareIdentListItems);
|
FItems:=TAVLTree.Create(@CompareIdentListItems);
|
||||||
FIdentView:=TAVLTree.Create(@CompareIdentListItemsForIdents);
|
FIdentView:=TAVLTree.Create(@CompareIdentListItemsForIdents);
|
||||||
|
FIdentSearchItem:=TIdentifierListItem.Create;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
destructor TIdentifierList.Destroy;
|
destructor TIdentifierList.Destroy;
|
||||||
@ -328,6 +337,7 @@ begin
|
|||||||
FItems.Free;
|
FItems.Free;
|
||||||
FIdentView.Free;
|
FIdentView.Free;
|
||||||
FFilteredList.Free;
|
FFilteredList.Free;
|
||||||
|
FIdentSearchItem.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -366,6 +376,15 @@ begin
|
|||||||
Result:=FFilteredList.Count;
|
Result:=FFilteredList.Count;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TIdentifierList.HasIdentifier(Identifier: PChar;
|
||||||
|
const ParamList: string): boolean;
|
||||||
|
begin
|
||||||
|
FIdentSearchItem.Identifier:=Identifier;
|
||||||
|
FIdentSearchItem.ParamList:='';
|
||||||
|
Result:=FIdentView.FindKey(FIdentSearchItem,
|
||||||
|
@CompareIdentListItemsForIdents)<>nil;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TIdentCompletionTool }
|
{ TIdentCompletionTool }
|
||||||
|
|
||||||
function TIdentCompletionTool.CollectAllIdentifiers(
|
function TIdentCompletionTool.CollectAllIdentifiers(
|
||||||
@ -437,9 +456,64 @@ begin
|
|||||||
CurrentIdentifierList.Add(NewItem);
|
CurrentIdentifierList.Add(NewItem);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TIdentCompletionTool.GatherPredefinedIdentifiers;
|
procedure TIdentCompletionTool.GatherPredefinedIdentifiers(CleanPos: integer;
|
||||||
|
const Context: TFindContext);
|
||||||
|
// Add predefined identifiers
|
||||||
|
|
||||||
|
function StatementLevel: integer;
|
||||||
|
var
|
||||||
|
ANode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
// ToDo:
|
Result:=0;
|
||||||
|
ANode:=Context.Node;
|
||||||
|
while (ANode<>nil) and (not (ANode.Desc in [ctnBeginBlock,ctnAsmBlock])) do
|
||||||
|
begin
|
||||||
|
ANode:=ANode.Parent;
|
||||||
|
inc(Result);
|
||||||
|
end;
|
||||||
|
if ANode=nil then Result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
NewItem: TIdentifierListItem;
|
||||||
|
ProcNode: TCodeTreeNode;
|
||||||
|
begin
|
||||||
|
if Context.Node.Desc in AllPascalStatements then begin
|
||||||
|
if Context.Tool.NodeIsInAMethod(Context.Node)
|
||||||
|
and (not CurrentIdentifierList.HasIdentifier('Self','')) then begin
|
||||||
|
// method body -> add 'Self'
|
||||||
|
NewItem:=TIdentifierListItem.Create;
|
||||||
|
NewItem.Compatibility:=icompUnknown;
|
||||||
|
NewItem.HasChilds:=true;
|
||||||
|
NewItem.Identifier:='Self';
|
||||||
|
NewItem.Level:=StatementLevel;
|
||||||
|
NewItem.Node:=nil;
|
||||||
|
NewItem.Tool:=nil;
|
||||||
|
NewItem.DefaultDesc:=ctnVarDefinition;
|
||||||
|
CurrentIdentifierList.Add(NewItem);
|
||||||
|
end;
|
||||||
|
ProcNode:=Context.Node.GetNodeOfType(ctnProcedure);
|
||||||
|
if Context.Tool.NodeIsFunction(ProcNode)
|
||||||
|
and (not CurrentIdentifierList.HasIdentifier('Result','')) then begin
|
||||||
|
// function body -> add 'Result'
|
||||||
|
NewItem:=TIdentifierListItem.Create;
|
||||||
|
NewItem.Compatibility:=icompUnknown;
|
||||||
|
NewItem.HasChilds:=false;
|
||||||
|
NewItem.Identifier:='Result';
|
||||||
|
NewItem.Level:=StatementLevel;
|
||||||
|
NewItem.Node:=nil;
|
||||||
|
NewItem.Tool:=nil;
|
||||||
|
NewItem.DefaultDesc:=ctnNone;
|
||||||
|
CurrentIdentifierList.Add(NewItem);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TIdentCompletionTool.GatherUsefulIdentifiers(CleanPos: integer;
|
||||||
|
const Context: TFindContext);
|
||||||
|
begin
|
||||||
|
GatherPredefinedIdentifiers(CleanPos,Context);
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TIdentCompletionTool.GatherIdentifiers(
|
function TIdentCompletionTool.GatherIdentifiers(
|
||||||
@ -519,11 +593,11 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
GatherContext.Tool.FindIdentifierInContext(Params);
|
GatherContext.Tool.FindIdentifierInContext(Params);
|
||||||
end;
|
end;
|
||||||
// add predefined identifiers
|
// add useful identifiers without context
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
writeln('TIdentCompletionTool.GatherIdentifiers G');
|
writeln('TIdentCompletionTool.GatherIdentifiers G');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
GatherPredefinedIdentifiers;
|
GatherUsefulIdentifiers(CleanCursorPos,GatherContext);
|
||||||
|
|
||||||
Result:=true;
|
Result:=true;
|
||||||
finally
|
finally
|
||||||
@ -541,15 +615,23 @@ end;
|
|||||||
function TIdentifierListItem.GetParamList: string;
|
function TIdentifierListItem.GetParamList: string;
|
||||||
begin
|
begin
|
||||||
if not FParamListValid then begin
|
if not FParamListValid then begin
|
||||||
if Node.Desc=ctnProcedure then
|
if (Node<>nil) and (Node.Desc=ctnProcedure) then
|
||||||
FParamList:=Tool.ExtractProcHead(Node,
|
FParamList:=Tool.ExtractProcHead(Node,
|
||||||
[phpWithoutClassKeyword,phpWithoutClassName,
|
[phpWithoutClassKeyword,phpWithoutClassName,
|
||||||
phpWithoutName,phpInUpperCase]);
|
phpWithoutName,phpInUpperCase])
|
||||||
|
else
|
||||||
|
FParamList:='';
|
||||||
FParamListValid:=true;
|
FParamListValid:=true;
|
||||||
end;
|
end;
|
||||||
Result:=FParamList;
|
Result:=FParamList;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TIdentifierListItem.SetParamList(const AValue: string);
|
||||||
|
begin
|
||||||
|
FParamList:=AValue;
|
||||||
|
FParamListValid:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
function TIdentifierListItem.AsString: string;
|
function TIdentifierListItem.AsString: string;
|
||||||
begin
|
begin
|
||||||
Result:=IdentifierCompatibilityNames[Compatibility];
|
Result:=IdentifierCompatibilityNames[Compatibility];
|
||||||
@ -560,11 +642,21 @@ begin
|
|||||||
Result:=Result+' History='+IntToStr(HistoryIndex);
|
Result:=Result+' History='+IntToStr(HistoryIndex);
|
||||||
Result:=Result+' Ident='+GetIdentifier(Identifier);
|
Result:=Result+' Ident='+GetIdentifier(Identifier);
|
||||||
Result:=Result+' Lvl='+IntToStr(Level);
|
Result:=Result+' Lvl='+IntToStr(Level);
|
||||||
|
if Tool<>nil then
|
||||||
Result:=Result+' File='+Tool.MainFilename;
|
Result:=Result+' File='+Tool.MainFilename;
|
||||||
|
if Node<>nil then
|
||||||
Result:=Result+' Node='+Node.DescAsString
|
Result:=Result+' Node='+Node.DescAsString
|
||||||
+' "'+StringToPascalConst(copy(Tool.Src,Node.StartPos,50))+'"';
|
+' "'+StringToPascalConst(copy(Tool.Src,Node.StartPos,50))+'"';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TIdentifierListItem.GetDesc: TCodeTreeNodeDesc;
|
||||||
|
begin
|
||||||
|
if Node<>nil then
|
||||||
|
Result:=Node.Desc
|
||||||
|
else
|
||||||
|
Result:=DefaultDesc;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TIdentifierHistoryList }
|
{ TIdentifierHistoryList }
|
||||||
|
|
||||||
procedure TIdentifierHistoryList.SetCapacity(const AValue: integer);
|
procedure TIdentifierHistoryList.SetCapacity(const AValue: integer);
|
||||||
@ -628,7 +720,7 @@ begin
|
|||||||
// create a new history item
|
// create a new history item
|
||||||
NewHistItem:=TIdentHistListItem.Create;
|
NewHistItem:=TIdentHistListItem.Create;
|
||||||
NewHistItem.Identifier:=GetIdentifier(NewItem.Identifier);
|
NewHistItem.Identifier:=GetIdentifier(NewItem.Identifier);
|
||||||
NewHistItem.NodeDesc:=NewItem.Node.Desc;
|
NewHistItem.NodeDesc:=NewItem.GetDesc;
|
||||||
NewHistItem.ParamList:=NewItem.ParamList;
|
NewHistItem.ParamList:=NewItem.ParamList;
|
||||||
AdjustIndex:=0;
|
AdjustIndex:=0;
|
||||||
end;
|
end;
|
||||||
|
|||||||
@ -81,17 +81,16 @@ var
|
|||||||
AColor: TColor;
|
AColor: TColor;
|
||||||
ANode: TCodeTreeNode;
|
ANode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
with ACanvas do begin
|
|
||||||
if CurrentCompletionType=ctIdentCompletion then begin
|
if CurrentCompletionType=ctIdentCompletion then begin
|
||||||
// draw
|
// draw
|
||||||
IdentItem:=CodeToolBoss.IdentifierList.FilteredItems[Index];
|
IdentItem:=CodeToolBoss.IdentifierList.FilteredItems[Index];
|
||||||
if IdentItem=nil then begin
|
if IdentItem=nil then begin
|
||||||
TextOut(x+1, y, 'PaintCompletionItem: BUG in codetools');
|
ACanvas.TextOut(x+1, y, 'PaintCompletionItem: BUG in codetools');
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
// first write the type
|
// first write the type
|
||||||
// var, procedure, property, function, type, const
|
// var, procedure, property, function, type, const
|
||||||
case IdentItem.Node.Desc of
|
case IdentItem.GetDesc of
|
||||||
|
|
||||||
ctnVarDefinition:
|
ctnVarDefinition:
|
||||||
begin
|
begin
|
||||||
@ -112,7 +111,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
ctnProcedure:
|
ctnProcedure:
|
||||||
if IdentItem.Tool.NodeIsFunction(IdentItem.Node) then begin
|
if (IdentItem.Node<>nil)
|
||||||
|
and IdentItem.Tool.NodeIsFunction(IdentItem.Node) then begin
|
||||||
AColor:=clTeal;
|
AColor:=clTeal;
|
||||||
s:='function';
|
s:='function';
|
||||||
end else begin
|
end else begin
|
||||||
@ -132,16 +132,17 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
SetFontColor(AColor);
|
SetFontColor(AColor);
|
||||||
TextOut(x+1,y,s);
|
ACanvas.TextOut(x+1,y,s);
|
||||||
inc(x,TextWidth('procedure '));
|
inc(x,ACanvas.TextWidth('procedure '));
|
||||||
|
|
||||||
SetFontColor(clBlack);
|
SetFontColor(clBlack);
|
||||||
Font.Style:=Font.Style+[fsBold];
|
ACanvas.Font.Style:=ACanvas.Font.Style+[fsBold];
|
||||||
s:=GetIdentifier(IdentItem.Identifier);
|
s:=GetIdentifier(IdentItem.Identifier);
|
||||||
TextOut(x+1,y,s);
|
ACanvas.TextOut(x+1,y,s);
|
||||||
inc(x,TextWidth(s));
|
inc(x,ACanvas.TextWidth(s));
|
||||||
Font.Style:=Font.Style-[fsBold];
|
ACanvas.Font.Style:=ACanvas.Font.Style-[fsBold];
|
||||||
|
|
||||||
|
if IdentItem.Node<>nil then begin
|
||||||
case IdentItem.Node.Desc of
|
case IdentItem.Node.Desc of
|
||||||
|
|
||||||
ctnProcedure:
|
ctnProcedure:
|
||||||
@ -181,9 +182,13 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
end else begin
|
||||||
|
// IdentItem.Node=nil
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
SetFontColor(clBlack);
|
SetFontColor(clBlack);
|
||||||
TextOut(x+1,y,s);
|
ACanvas.TextOut(x+1,y,s);
|
||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
// parse AKey for text and style
|
// parse AKey for text and style
|
||||||
@ -193,7 +198,8 @@ begin
|
|||||||
#1, #2:
|
#1, #2:
|
||||||
begin
|
begin
|
||||||
// set color
|
// set color
|
||||||
Font.Color := (Ord(AKey[i + 3]) shl 8 + Ord(AKey[i + 2])) shl 8
|
ACanvas.Font.Color := (Ord(AKey[i + 3]) shl 8
|
||||||
|
+ Ord(AKey[i + 2])) shl 8
|
||||||
+ Ord(AKey[i + 1]);
|
+ Ord(AKey[i + 1]);
|
||||||
inc(i, 4);
|
inc(i, 4);
|
||||||
end;
|
end;
|
||||||
@ -201,24 +207,23 @@ begin
|
|||||||
begin
|
begin
|
||||||
// set style
|
// set style
|
||||||
case AKey[i + 1] of
|
case AKey[i + 1] of
|
||||||
'B': Font.Style := Font.Style + [fsBold];
|
'B': ACanvas.Font.Style := ACanvas.Font.Style + [fsBold];
|
||||||
'b': Font.Style := Font.Style - [fsBold];
|
'b': ACanvas.Font.Style := ACanvas.Font.Style - [fsBold];
|
||||||
'U': Font.Style := Font.Style + [fsUnderline];
|
'U': ACanvas.Font.Style := ACanvas.Font.Style + [fsUnderline];
|
||||||
'u': Font.Style := Font.Style - [fsUnderline];
|
'u': ACanvas.Font.Style := ACanvas.Font.Style - [fsUnderline];
|
||||||
'I': Font.Style := Font.Style + [fsItalic];
|
'I': ACanvas.Font.Style := ACanvas.Font.Style + [fsItalic];
|
||||||
'i': Font.Style := Font.Style - [fsItalic];
|
'i': ACanvas.Font.Style := ACanvas.Font.Style - [fsItalic];
|
||||||
end;
|
end;
|
||||||
inc(i, 2);
|
inc(i, 2);
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
TextOut(x+1, y, AKey[i]);
|
ACanvas.TextOut(x+1, y, AKey[i]);
|
||||||
x := x + TextWidth(AKey[i]);
|
x := x + ACanvas.TextWidth(AKey[i]);
|
||||||
inc(i);
|
inc(i);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
|
||||||
|
|
||||||
function GetIdentCompletionValue(aCompletion : TSynCompletion;
|
function GetIdentCompletionValue(aCompletion : TSynCompletion;
|
||||||
var ValueType: TIdentComplValue): string;
|
var ValueType: TIdentComplValue): string;
|
||||||
@ -231,14 +236,16 @@ begin
|
|||||||
ValueType:=icvIdentifier;
|
ValueType:=icvIdentifier;
|
||||||
if IdentItem<>nil then begin
|
if IdentItem<>nil then begin
|
||||||
Result:=GetIdentifier(IdentItem.Identifier);
|
Result:=GetIdentifier(IdentItem.Identifier);
|
||||||
case IdentItem.Node.Desc of
|
case IdentItem.GetDesc of
|
||||||
|
|
||||||
ctnProcedure:
|
ctnProcedure:
|
||||||
if IdentItem.Tool.ProcNodeHasParamList(IdentItem.Node) then
|
if (IdentItem.Node<>nil)
|
||||||
|
and IdentItem.Tool.ProcNodeHasParamList(IdentItem.Node) then
|
||||||
ValueType:=icvProcWithParams;
|
ValueType:=icvProcWithParams;
|
||||||
|
|
||||||
ctnProperty:
|
ctnProperty:
|
||||||
if IdentItem.Tool.PropertyNodeHasParamList(IdentItem.Node) then
|
if (IdentItem.Node<>nil)
|
||||||
|
and IdentItem.Tool.PropertyNodeHasParamList(IdentItem.Node) then
|
||||||
ValueType:=icvIndexedProp;
|
ValueType:=icvIndexedProp;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user