mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-22 12:28:15 +02: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;
|
||||
FParamListValid: boolean;
|
||||
function GetParamList: string;
|
||||
procedure SetParamList(const AValue: string);
|
||||
public
|
||||
Compatibility: TIdentifierCompatibility;
|
||||
HasChilds: boolean; // identifier can contain childs (class, record)
|
||||
@ -87,8 +88,10 @@ type
|
||||
Level: integer;
|
||||
Node: TCodeTreeNode;
|
||||
Tool: TFindDeclarationTool;
|
||||
DefaultDesc: TCodeTreeNodeDesc;
|
||||
function AsString: string;
|
||||
property ParamList: string read GetParamList;
|
||||
function GetDesc: TCodeTreeNodeDesc;
|
||||
property ParamList: string read GetParamList write SetParamList;
|
||||
end;
|
||||
|
||||
TIdentifierListFlag = (ilfFilteredListNeedsUpdate);
|
||||
@ -101,6 +104,7 @@ type
|
||||
FHistory: TIdentifierHistoryList;
|
||||
FItems: TAVLTree; // tree of TIdentifierListItem (completely sorted)
|
||||
FIdentView: TAVLTree; // tree of TIdentHistListItem sorted for identifiers
|
||||
FIdentSearchItem: TIdentifierListItem;
|
||||
FPrefix: string;
|
||||
procedure SetHistory(const AValue: TIdentifierHistoryList);
|
||||
procedure UpdateFilteredList;
|
||||
@ -113,6 +117,7 @@ type
|
||||
procedure Add(NewItem: TIdentifierListItem);
|
||||
function Count: integer;
|
||||
function GetFilteredCount: integer;
|
||||
function HasIdentifier(Identifier: PChar; const ParamList: string): boolean;
|
||||
public
|
||||
property Prefix: string read FPrefix write SetPrefix;
|
||||
property FilteredItems[Index: integer]: TIdentifierListItem
|
||||
@ -159,7 +164,10 @@ type
|
||||
CurrentIdentifierList: TIdentifierList;
|
||||
function CollectAllIdentifiers(Params: TFindDeclarationParams;
|
||||
const FoundContext: TFindContext): TIdentifierFoundResult;
|
||||
procedure GatherPredefinedIdentifiers;
|
||||
procedure GatherPredefinedIdentifiers(CleanPos: integer;
|
||||
const Context: TFindContext);
|
||||
procedure GatherUsefulIdentifiers(CleanPos: integer;
|
||||
const Context: TFindContext);
|
||||
public
|
||||
function GatherIdentifiers(const CursorPos: TCodeXYPosition;
|
||||
var IdentifierList: TIdentifierList): boolean;
|
||||
@ -320,6 +328,7 @@ begin
|
||||
FFlags:=[ilfFilteredListNeedsUpdate];
|
||||
FItems:=TAVLTree.Create(@CompareIdentListItems);
|
||||
FIdentView:=TAVLTree.Create(@CompareIdentListItemsForIdents);
|
||||
FIdentSearchItem:=TIdentifierListItem.Create;
|
||||
end;
|
||||
|
||||
destructor TIdentifierList.Destroy;
|
||||
@ -328,6 +337,7 @@ begin
|
||||
FItems.Free;
|
||||
FIdentView.Free;
|
||||
FFilteredList.Free;
|
||||
FIdentSearchItem.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
@ -366,6 +376,15 @@ begin
|
||||
Result:=FFilteredList.Count;
|
||||
end;
|
||||
|
||||
function TIdentifierList.HasIdentifier(Identifier: PChar;
|
||||
const ParamList: string): boolean;
|
||||
begin
|
||||
FIdentSearchItem.Identifier:=Identifier;
|
||||
FIdentSearchItem.ParamList:='';
|
||||
Result:=FIdentView.FindKey(FIdentSearchItem,
|
||||
@CompareIdentListItemsForIdents)<>nil;
|
||||
end;
|
||||
|
||||
{ TIdentCompletionTool }
|
||||
|
||||
function TIdentCompletionTool.CollectAllIdentifiers(
|
||||
@ -437,9 +456,64 @@ begin
|
||||
CurrentIdentifierList.Add(NewItem);
|
||||
end;
|
||||
|
||||
procedure TIdentCompletionTool.GatherPredefinedIdentifiers;
|
||||
procedure TIdentCompletionTool.GatherPredefinedIdentifiers(CleanPos: integer;
|
||||
const Context: TFindContext);
|
||||
// Add predefined identifiers
|
||||
|
||||
function StatementLevel: integer;
|
||||
var
|
||||
ANode: TCodeTreeNode;
|
||||
begin
|
||||
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
|
||||
// ToDo:
|
||||
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;
|
||||
|
||||
function TIdentCompletionTool.GatherIdentifiers(
|
||||
@ -519,11 +593,11 @@ begin
|
||||
{$ENDIF}
|
||||
GatherContext.Tool.FindIdentifierInContext(Params);
|
||||
end;
|
||||
// add predefined identifiers
|
||||
// add useful identifiers without context
|
||||
{$IFDEF CTDEBUG}
|
||||
writeln('TIdentCompletionTool.GatherIdentifiers G');
|
||||
{$ENDIF}
|
||||
GatherPredefinedIdentifiers;
|
||||
GatherUsefulIdentifiers(CleanCursorPos,GatherContext);
|
||||
|
||||
Result:=true;
|
||||
finally
|
||||
@ -541,15 +615,23 @@ end;
|
||||
function TIdentifierListItem.GetParamList: string;
|
||||
begin
|
||||
if not FParamListValid then begin
|
||||
if Node.Desc=ctnProcedure then
|
||||
if (Node<>nil) and (Node.Desc=ctnProcedure) then
|
||||
FParamList:=Tool.ExtractProcHead(Node,
|
||||
[phpWithoutClassKeyword,phpWithoutClassName,
|
||||
phpWithoutName,phpInUpperCase]);
|
||||
phpWithoutName,phpInUpperCase])
|
||||
else
|
||||
FParamList:='';
|
||||
FParamListValid:=true;
|
||||
end;
|
||||
Result:=FParamList;
|
||||
end;
|
||||
|
||||
procedure TIdentifierListItem.SetParamList(const AValue: string);
|
||||
begin
|
||||
FParamList:=AValue;
|
||||
FParamListValid:=true;
|
||||
end;
|
||||
|
||||
function TIdentifierListItem.AsString: string;
|
||||
begin
|
||||
Result:=IdentifierCompatibilityNames[Compatibility];
|
||||
@ -560,9 +642,19 @@ begin
|
||||
Result:=Result+' History='+IntToStr(HistoryIndex);
|
||||
Result:=Result+' Ident='+GetIdentifier(Identifier);
|
||||
Result:=Result+' Lvl='+IntToStr(Level);
|
||||
Result:=Result+' File='+Tool.MainFilename;
|
||||
Result:=Result+' Node='+Node.DescAsString
|
||||
+' "'+StringToPascalConst(copy(Tool.Src,Node.StartPos,50))+'"';
|
||||
if Tool<>nil then
|
||||
Result:=Result+' File='+Tool.MainFilename;
|
||||
if Node<>nil then
|
||||
Result:=Result+' Node='+Node.DescAsString
|
||||
+' "'+StringToPascalConst(copy(Tool.Src,Node.StartPos,50))+'"';
|
||||
end;
|
||||
|
||||
function TIdentifierListItem.GetDesc: TCodeTreeNodeDesc;
|
||||
begin
|
||||
if Node<>nil then
|
||||
Result:=Node.Desc
|
||||
else
|
||||
Result:=DefaultDesc;
|
||||
end;
|
||||
|
||||
{ TIdentifierHistoryList }
|
||||
@ -628,7 +720,7 @@ begin
|
||||
// create a new history item
|
||||
NewHistItem:=TIdentHistListItem.Create;
|
||||
NewHistItem.Identifier:=GetIdentifier(NewItem.Identifier);
|
||||
NewHistItem.NodeDesc:=NewItem.Node.Desc;
|
||||
NewHistItem.NodeDesc:=NewItem.GetDesc;
|
||||
NewHistItem.ParamList:=NewItem.ParamList;
|
||||
AdjustIndex:=0;
|
||||
end;
|
||||
|
@ -81,69 +81,70 @@ var
|
||||
AColor: TColor;
|
||||
ANode: TCodeTreeNode;
|
||||
begin
|
||||
with ACanvas do begin
|
||||
if CurrentCompletionType=ctIdentCompletion then begin
|
||||
// draw
|
||||
IdentItem:=CodeToolBoss.IdentifierList.FilteredItems[Index];
|
||||
if IdentItem=nil then begin
|
||||
TextOut(x+1, y, 'PaintCompletionItem: BUG in codetools');
|
||||
exit;
|
||||
if CurrentCompletionType=ctIdentCompletion then begin
|
||||
// draw
|
||||
IdentItem:=CodeToolBoss.IdentifierList.FilteredItems[Index];
|
||||
if IdentItem=nil then begin
|
||||
ACanvas.TextOut(x+1, y, 'PaintCompletionItem: BUG in codetools');
|
||||
exit;
|
||||
end;
|
||||
// first write the type
|
||||
// var, procedure, property, function, type, const
|
||||
case IdentItem.GetDesc of
|
||||
|
||||
ctnVarDefinition:
|
||||
begin
|
||||
AColor:=clMaroon;
|
||||
s:='var';
|
||||
end;
|
||||
// first write the type
|
||||
// var, procedure, property, function, type, const
|
||||
case IdentItem.Node.Desc of
|
||||
|
||||
ctnVarDefinition:
|
||||
begin
|
||||
AColor:=clMaroon;
|
||||
s:='var';
|
||||
end;
|
||||
ctnTypeDefinition:
|
||||
begin
|
||||
AColor:=clDkGray;
|
||||
s:='type';
|
||||
end;
|
||||
|
||||
ctnTypeDefinition:
|
||||
begin
|
||||
AColor:=clDkGray;
|
||||
s:='type';
|
||||
end;
|
||||
ctnConstDefinition:
|
||||
begin
|
||||
AColor:=clOlive;
|
||||
s:='const';
|
||||
end;
|
||||
|
||||
ctnConstDefinition:
|
||||
begin
|
||||
AColor:=clOlive;
|
||||
s:='const';
|
||||
end;
|
||||
|
||||
ctnProcedure:
|
||||
if IdentItem.Tool.NodeIsFunction(IdentItem.Node) then begin
|
||||
AColor:=clTeal;
|
||||
s:='function';
|
||||
end else begin
|
||||
AColor:=clNavy;
|
||||
s:='procedure';
|
||||
end;
|
||||
|
||||
ctnProperty:
|
||||
begin
|
||||
AColor:=clPurple;
|
||||
s:='property';
|
||||
end;
|
||||
|
||||
else
|
||||
AColor:=clGray;
|
||||
s:='';
|
||||
ctnProcedure:
|
||||
if (IdentItem.Node<>nil)
|
||||
and IdentItem.Tool.NodeIsFunction(IdentItem.Node) then begin
|
||||
AColor:=clTeal;
|
||||
s:='function';
|
||||
end else begin
|
||||
AColor:=clNavy;
|
||||
s:='procedure';
|
||||
end;
|
||||
|
||||
SetFontColor(AColor);
|
||||
TextOut(x+1,y,s);
|
||||
inc(x,TextWidth('procedure '));
|
||||
ctnProperty:
|
||||
begin
|
||||
AColor:=clPurple;
|
||||
s:='property';
|
||||
end;
|
||||
|
||||
SetFontColor(clBlack);
|
||||
Font.Style:=Font.Style+[fsBold];
|
||||
s:=GetIdentifier(IdentItem.Identifier);
|
||||
TextOut(x+1,y,s);
|
||||
inc(x,TextWidth(s));
|
||||
Font.Style:=Font.Style-[fsBold];
|
||||
else
|
||||
AColor:=clGray;
|
||||
s:='';
|
||||
end;
|
||||
|
||||
SetFontColor(AColor);
|
||||
ACanvas.TextOut(x+1,y,s);
|
||||
inc(x,ACanvas.TextWidth('procedure '));
|
||||
|
||||
SetFontColor(clBlack);
|
||||
ACanvas.Font.Style:=ACanvas.Font.Style+[fsBold];
|
||||
s:=GetIdentifier(IdentItem.Identifier);
|
||||
ACanvas.TextOut(x+1,y,s);
|
||||
inc(x,ACanvas.TextWidth(s));
|
||||
ACanvas.Font.Style:=ACanvas.Font.Style-[fsBold];
|
||||
|
||||
if IdentItem.Node<>nil then begin
|
||||
case IdentItem.Node.Desc of
|
||||
|
||||
|
||||
ctnProcedure:
|
||||
begin
|
||||
s:=IdentItem.Tool.ExtractProcHead(IdentItem.Node,
|
||||
@ -151,14 +152,14 @@ begin
|
||||
phpWithParameterNames,phpWithDefaultValues,phpWithResultType,
|
||||
phpWithOfObject]);
|
||||
end;
|
||||
|
||||
|
||||
ctnProperty:
|
||||
begin
|
||||
s:=IdentItem.Tool.ExtractProperty(IdentItem.Node,
|
||||
[phpWithoutName,phpWithVarModifiers,
|
||||
phpWithParameterNames,phpWithDefaultValues,phpWithResultType]);
|
||||
end;
|
||||
|
||||
|
||||
ctnVarDefinition:
|
||||
begin
|
||||
ANode:=IdentItem.Tool.FindTypeNodeOfDefinition(IdentItem.Node);
|
||||
@ -179,42 +180,46 @@ begin
|
||||
|
||||
else
|
||||
exit;
|
||||
|
||||
end;
|
||||
|
||||
SetFontColor(clBlack);
|
||||
TextOut(x+1,y,s);
|
||||
|
||||
end;
|
||||
end else begin
|
||||
// parse AKey for text and style
|
||||
i := 1;
|
||||
while i <= Length(AKey) do begin
|
||||
case AKey[i] of
|
||||
#1, #2:
|
||||
begin
|
||||
// set color
|
||||
Font.Color := (Ord(AKey[i + 3]) shl 8 + Ord(AKey[i + 2])) shl 8
|
||||
+ Ord(AKey[i + 1]);
|
||||
inc(i, 4);
|
||||
end;
|
||||
#3:
|
||||
begin
|
||||
// set style
|
||||
case AKey[i + 1] of
|
||||
'B': Font.Style := Font.Style + [fsBold];
|
||||
'b': Font.Style := Font.Style - [fsBold];
|
||||
'U': Font.Style := Font.Style + [fsUnderline];
|
||||
'u': Font.Style := Font.Style - [fsUnderline];
|
||||
'I': Font.Style := Font.Style + [fsItalic];
|
||||
'i': Font.Style := Font.Style - [fsItalic];
|
||||
end;
|
||||
inc(i, 2);
|
||||
end;
|
||||
else
|
||||
TextOut(x+1, y, AKey[i]);
|
||||
x := x + TextWidth(AKey[i]);
|
||||
inc(i);
|
||||
// IdentItem.Node=nil
|
||||
exit;
|
||||
end;
|
||||
|
||||
SetFontColor(clBlack);
|
||||
ACanvas.TextOut(x+1,y,s);
|
||||
|
||||
end else begin
|
||||
// parse AKey for text and style
|
||||
i := 1;
|
||||
while i <= Length(AKey) do begin
|
||||
case AKey[i] of
|
||||
#1, #2:
|
||||
begin
|
||||
// set color
|
||||
ACanvas.Font.Color := (Ord(AKey[i + 3]) shl 8
|
||||
+ Ord(AKey[i + 2])) shl 8
|
||||
+ Ord(AKey[i + 1]);
|
||||
inc(i, 4);
|
||||
end;
|
||||
#3:
|
||||
begin
|
||||
// set style
|
||||
case AKey[i + 1] of
|
||||
'B': ACanvas.Font.Style := ACanvas.Font.Style + [fsBold];
|
||||
'b': ACanvas.Font.Style := ACanvas.Font.Style - [fsBold];
|
||||
'U': ACanvas.Font.Style := ACanvas.Font.Style + [fsUnderline];
|
||||
'u': ACanvas.Font.Style := ACanvas.Font.Style - [fsUnderline];
|
||||
'I': ACanvas.Font.Style := ACanvas.Font.Style + [fsItalic];
|
||||
'i': ACanvas.Font.Style := ACanvas.Font.Style - [fsItalic];
|
||||
end;
|
||||
inc(i, 2);
|
||||
end;
|
||||
else
|
||||
ACanvas.TextOut(x+1, y, AKey[i]);
|
||||
x := x + ACanvas.TextWidth(AKey[i]);
|
||||
inc(i);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -231,14 +236,16 @@ begin
|
||||
ValueType:=icvIdentifier;
|
||||
if IdentItem<>nil then begin
|
||||
Result:=GetIdentifier(IdentItem.Identifier);
|
||||
case IdentItem.Node.Desc of
|
||||
case IdentItem.GetDesc of
|
||||
|
||||
ctnProcedure:
|
||||
if IdentItem.Tool.ProcNodeHasParamList(IdentItem.Node) then
|
||||
if (IdentItem.Node<>nil)
|
||||
and IdentItem.Tool.ProcNodeHasParamList(IdentItem.Node) then
|
||||
ValueType:=icvProcWithParams;
|
||||
|
||||
ctnProperty:
|
||||
if IdentItem.Tool.PropertyNodeHasParamList(IdentItem.Node) then
|
||||
if (IdentItem.Node<>nil)
|
||||
and IdentItem.Tool.PropertyNodeHasParamList(IdentItem.Node) then
|
||||
ValueType:=icvIndexedProp;
|
||||
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user