ident completion: added special identifiers Self and Result

git-svn-id: trunk@3784 -
This commit is contained in:
mattias 2003-01-04 13:12:00 +00:00
parent 793dcc8be5
commit cacafb6ba0
2 changed files with 203 additions and 104 deletions

View File

@ -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
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 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; 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;

View File

@ -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,23 +207,22 @@ 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;
@ -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;