mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-12 06:16:05 +02:00
codetools: code completion: implemented adding methog declaration for method body at cursor
git-svn-id: trunk@10386 -
This commit is contained in:
parent
8c34006c95
commit
735b70957a
@ -172,6 +172,10 @@ type
|
|||||||
OldTopLine: integer; CursorNode: TCodeTreeNode;
|
OldTopLine: integer; CursorNode: TCodeTreeNode;
|
||||||
var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
||||||
SourceChangeCache: TSourceChangeCache): boolean;
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
|
function CompleteMethod(CleanCursorPos, OldTopLine: integer;
|
||||||
|
CursorNode: TCodeTreeNode;
|
||||||
|
var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
||||||
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
protected
|
protected
|
||||||
property CodeCompleteClassNode: TCodeTreeNode
|
property CodeCompleteClassNode: TCodeTreeNode
|
||||||
read FCodeCompleteClassNode write SetCodeCompleteClassNode;
|
read FCodeCompleteClassNode write SetCodeCompleteClassNode;
|
||||||
@ -325,7 +329,7 @@ procedure TCodeCompletionCodeTool.AddClassInsertion(
|
|||||||
var NewInsert, InsertPos, LastInsertPos: TCodeTreeNodeExtension;
|
var NewInsert, InsertPos, LastInsertPos: TCodeTreeNodeExtension;
|
||||||
begin
|
begin
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DebugLn('[TCodeCompletionCodeTool.AddClassInsertion] ',CleanDef,',',Def,',',Identifiername);
|
DebugLn('[TCodeCompletionCodeTool.AddClassInsertion] CleanDef="',CleanDef,'" Def="',Def,'" Identifiername="',Identifiername,'" Body="',Body,'"');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
NewInsert:=NodeExtMemManager.NewNode;
|
NewInsert:=NodeExtMemManager.NewNode;
|
||||||
with NewInsert do begin
|
with NewInsert do begin
|
||||||
@ -991,6 +995,72 @@ begin
|
|||||||
NewType,NewPos,NewTopLine,SourceChangeCache);
|
NewType,NewPos,NewTopLine,SourceChangeCache);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCodeCompletionCodeTool.CompleteMethod(
|
||||||
|
CleanCursorPos, OldTopLine: integer;
|
||||||
|
CursorNode: TCodeTreeNode;
|
||||||
|
var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
||||||
|
SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
|
var
|
||||||
|
CurClassName: String;
|
||||||
|
ProcNode: TCodeTreeNode;
|
||||||
|
CleanProcCode: String;
|
||||||
|
ProcCode: String;
|
||||||
|
ProcName: String;
|
||||||
|
OldCodePos: TCodePosition;
|
||||||
|
begin
|
||||||
|
Result:=false;
|
||||||
|
|
||||||
|
// check if cursor in a method
|
||||||
|
ProcNode:=CursorNode.GetNodeOfType(ctnProcedure);
|
||||||
|
if (ProcNode=nil) and (CursorNode.Desc=ctnProcedure) then
|
||||||
|
ProcNode:=CursorNode;
|
||||||
|
if (ProcNode=nil) or (ProcNode.Desc<>ctnProcedure)
|
||||||
|
or ((ProcNode.SubDesc and ctnsForwardDeclaration)<>0)
|
||||||
|
or (not NodeIsMethodBody(ProcNode)) then begin
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// find corresponding class declaration
|
||||||
|
CurClassName:=ExtractClassNameOfProcNode(ProcNode);
|
||||||
|
if CurClassName='' then begin
|
||||||
|
DebugLn(['CompleteMethod ExtractClassNameOfProcNode failed']);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
//DebugLn(['CompleteMethod CurClassName=',CurClassName]);
|
||||||
|
CodeCompleteClassNode:=FindClassNodeInUnit(CurClassName,true,false,false,true);
|
||||||
|
|
||||||
|
// check if method declaration already exists
|
||||||
|
ProcName:=ExtractProcName(ProcNode,[phpWithoutClassName]);
|
||||||
|
CleanProcCode:=ExtractProcHead(ProcNode,
|
||||||
|
[phpWithoutClassKeyword,phpWithoutClassName,phpInUpperCase]);
|
||||||
|
if ProcExistsInCodeCompleteClass(CleanProcCode) then begin
|
||||||
|
// proc exists already
|
||||||
|
MoveCursorToCleanPos(CleanCursorPos);
|
||||||
|
RaiseExceptionFmt(ctsIdentifierAlreadyDefined,[ProcName]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
// store old cursor position
|
||||||
|
if not CleanPosToCodePos(CleanCursorPos,OldCodePos) then begin
|
||||||
|
RaiseException('TCodeCompletionCodeTool.AddLocalVariable Internal Error: '
|
||||||
|
+'CleanPosToCodePos');
|
||||||
|
end;
|
||||||
|
|
||||||
|
CodeCompleteSrcChgCache:=SourceChangeCache;
|
||||||
|
|
||||||
|
// add method declaration
|
||||||
|
ProcCode:=ExtractProcHead(ProcNode,
|
||||||
|
[phpWithStart,phpWithoutClassName,phpWithVarModifiers,phpWithParameterNames,
|
||||||
|
phpWithDefaultValues,phpWithResultType,phpWithCallingSpecs]);
|
||||||
|
AddClassInsertion(CleanProcCode,ProcCode,ProcName,ncpPrivateProcs);
|
||||||
|
|
||||||
|
// apply changes
|
||||||
|
Result:=ApplyClassCompletion;
|
||||||
|
|
||||||
|
// adjust cursor position
|
||||||
|
AdjustCursor(OldCodePos,OldTopLine,NewPos,NewTopLine);
|
||||||
|
//DebugLn(['TCodeCompletionCodeTool.CompleteMethod END OldCodePos.P=',OldCodePos.P,' OldTopLine=',OldTopLine,' NewPos=',DbgsCXY(NewPos),' NewTopLine=',NewTopLine]);
|
||||||
|
end;
|
||||||
|
|
||||||
function TCodeCompletionCodeTool.AddPublishedVariable(const UpperClassName,
|
function TCodeCompletionCodeTool.AddPublishedVariable(const UpperClassName,
|
||||||
VarName, VarType: string; SourceChangeCache: TSourceChangeCache): boolean;
|
VarName, VarType: string; SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
begin
|
begin
|
||||||
@ -1004,7 +1074,7 @@ begin
|
|||||||
CodeCompleteClassNode:=FindClassNodeInInterface(UpperClassName,true,false,true);
|
CodeCompleteClassNode:=FindClassNodeInInterface(UpperClassName,true,false,true);
|
||||||
CodeCompleteSrcChgCache:=SourceChangeCache;
|
CodeCompleteSrcChgCache:=SourceChangeCache;
|
||||||
// check if variable already exists
|
// check if variable already exists
|
||||||
if VarExistsInCodeCompleteClass(UpperCaseStr(VarName)) then begin
|
if not VarExistsInCodeCompleteClass(UpperCaseStr(VarName)) then begin
|
||||||
|
|
||||||
end else begin
|
end else begin
|
||||||
AddClassInsertion(UpperCaseStr(VarName),
|
AddClassInsertion(UpperCaseStr(VarName),
|
||||||
@ -1028,7 +1098,7 @@ begin
|
|||||||
BuildTree(false);
|
BuildTree(false);
|
||||||
if not EndOfSourceFound then exit;
|
if not EndOfSourceFound then exit;
|
||||||
if (SourceChangeCache=nil) or (Scanner=nil) then exit;
|
if (SourceChangeCache=nil) or (Scanner=nil) then exit;
|
||||||
ClassNode:=FindClassNodeInInterface(UpperClassName,true,false,true);
|
ClassNode:=FindClassNodeInUnit(UpperClassName,true,false,false,true);
|
||||||
if (ClassNode=nil) then exit;
|
if (ClassNode=nil) then exit;
|
||||||
CodeCompleteClassNode:=ClassNode;
|
CodeCompleteClassNode:=ClassNode;
|
||||||
CodeCompleteSrcChgCache:=SourceChangeCache;
|
CodeCompleteSrcChgCache:=SourceChangeCache;
|
||||||
@ -2554,7 +2624,7 @@ function TCodeCompletionCodeTool.CompleteCode(CursorPos: TCodeXYPosition;
|
|||||||
var CleanCursorPos, Indent, insertPos: integer;
|
var CleanCursorPos, Indent, insertPos: integer;
|
||||||
CursorNode, ProcNode, ImplementationNode, SectionNode, AClassNode,
|
CursorNode, ProcNode, ImplementationNode, SectionNode, AClassNode,
|
||||||
ANode: TCodeTreeNode;
|
ANode: TCodeTreeNode;
|
||||||
ProcCode: string;
|
OldCleanCursorPos: LongInt;
|
||||||
|
|
||||||
procedure CompleteClass;
|
procedure CompleteClass;
|
||||||
var
|
var
|
||||||
@ -2663,11 +2733,6 @@ var CleanCursorPos, Indent, insertPos: integer;
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure CompleteMethod;
|
|
||||||
begin
|
|
||||||
// ToDo
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure CompleteForwardProcs;
|
procedure CompleteForwardProcs;
|
||||||
// add proc bodies for forward procs
|
// add proc bodies for forward procs
|
||||||
var
|
var
|
||||||
@ -2676,6 +2741,7 @@ var CleanCursorPos, Indent, insertPos: integer;
|
|||||||
StartProcNode: TCodeTreeNode;
|
StartProcNode: TCodeTreeNode;
|
||||||
CurProcNode: TCodeTreeNode;
|
CurProcNode: TCodeTreeNode;
|
||||||
EndProcNode: TCodeTreeNode;
|
EndProcNode: TCodeTreeNode;
|
||||||
|
ProcCode: String;
|
||||||
begin
|
begin
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DebugLn('TCodeCompletionCodeTool.CompleteCode in a forward procedure ... ');
|
DebugLn('TCodeCompletionCodeTool.CompleteCode in a forward procedure ... ');
|
||||||
@ -3079,10 +3145,13 @@ var CleanCursorPos, Indent, insertPos: integer;
|
|||||||
// var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
// var NewPos: TCodeXYPosition; var NewTopLine: integer;
|
||||||
// SourceChangeCache: TSourceChangeCache): boolean;
|
// SourceChangeCache: TSourceChangeCache): boolean;
|
||||||
begin
|
begin
|
||||||
|
//DebugLn(['TCodeCompletionCodeTool.CompleteCode CursorPos=',DbgsCXY(CursorPos),' OldTopLine=',OldTopLine]);
|
||||||
|
|
||||||
Result:=false;
|
Result:=false;
|
||||||
if (SourceChangeCache=nil) then
|
if (SourceChangeCache=nil) then
|
||||||
RaiseException('need a SourceChangeCache');
|
RaiseException('need a SourceChangeCache');
|
||||||
BuildTreeAndGetCleanPos(trAll,CursorPos, CleanCursorPos,[]);
|
BuildTreeAndGetCleanPos(trAll,CursorPos, CleanCursorPos,[]);
|
||||||
|
OldCleanCursorPos:=CleanCursorPos;
|
||||||
NewPos:=CleanCodeXYPosition;
|
NewPos:=CleanCodeXYPosition;
|
||||||
NewTopLine:=0;
|
NewTopLine:=0;
|
||||||
|
|
||||||
@ -3136,25 +3205,19 @@ begin
|
|||||||
if Result then exit;
|
if Result then exit;
|
||||||
|
|
||||||
// test if Local variable assignment
|
// test if Local variable assignment
|
||||||
Result:=CompleteLocalVariableAssignment(CleanCursorPos,OldTopLine,CursorNode,
|
Result:=CompleteLocalVariableAssignment(CleanCursorPos,OldTopLine,
|
||||||
NewPos,NewTopLine,SourceChangeCache);
|
CursorNode,NewPos,NewTopLine,SourceChangeCache);
|
||||||
if Result then exit;
|
if Result then exit;
|
||||||
|
|
||||||
// test if undeclared local variable as parameter
|
// test if undeclared local variable as parameter
|
||||||
Result:=CompleteLocalVariableAsParameter(CleanCursorPos,OldTopLine,CursorNode,
|
Result:=CompleteLocalVariableAsParameter(CleanCursorPos,OldTopLine,
|
||||||
NewPos,NewTopLine,SourceChangeCache);
|
CursorNode,NewPos,NewTopLine,SourceChangeCache);
|
||||||
if Result then exit;
|
if Result then exit;
|
||||||
|
|
||||||
// test if method body
|
// test if method body
|
||||||
ProcNode:=CursorNode.GetNodeOfType(ctnProcedure);
|
Result:=CompleteMethod(OldCleanCursorPos,OldTopLine,CursorNode,
|
||||||
if (ProcNode=nil) and (CursorNode.Desc=ctnProcedure) then
|
NewPos,NewTopLine,SourceChangeCache);
|
||||||
ProcNode:=CursorNode;
|
if Result then exit;
|
||||||
if (ProcNode<>nil) and (ProcNode.Desc=ctnProcedure)
|
|
||||||
and ((ProcNode.SubDesc and ctnsForwardDeclaration)=0)
|
|
||||||
and NodeIsMethodBody(ProcNode) then begin
|
|
||||||
CompleteMethod;
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DebugLn('TCodeCompletionCodeTool.CompleteCode nothing to complete ... ');
|
DebugLn('TCodeCompletionCodeTool.CompleteCode nothing to complete ... ');
|
||||||
|
@ -4466,29 +4466,25 @@ begin
|
|||||||
Result:=FindIdentifierInContext(Params);
|
Result:=FindIdentifierInContext(Params);
|
||||||
Params.Load(OldInput);
|
Params.Load(OldInput);
|
||||||
|
|
||||||
|
if (Params.NewCodeTool<>Self) then Result:=false;
|
||||||
|
|
||||||
// save result in cache
|
// save result in cache
|
||||||
if Params.Flags*[fdfCollect,fdfDoNotCache]=[] then begin
|
if Params.Flags*[fdfCollect,fdfDoNotCache]=[] then begin
|
||||||
if FInterfaceIdentifierCache=nil then
|
if FInterfaceIdentifierCache=nil then
|
||||||
FInterfaceIdentifierCache:=TInterfaceIdentifierCache.Create(Self);
|
FInterfaceIdentifierCache:=TInterfaceIdentifierCache.Create(Self);
|
||||||
if Result and (Params.NewCodeTool=Self) then begin
|
if Result then begin
|
||||||
// identifier exists in interface
|
// identifier exists in interface
|
||||||
if ([fdfDoNotCache,fdfCollect]*Params.Flags=[])
|
if (Params.NewNode<>nil) and (Params.NewNode.Desc=ctnProcedure) then begin
|
||||||
and ([fodDoNotCache]*Params.NewFlags=[]) then begin
|
//DebugLn('NOTE: TFindDeclarationTool.FindIdentifierInInterface Node is proc');
|
||||||
if (Params.NewNode<>nil) and (Params.NewNode.Desc=ctnProcedure) then begin
|
// ToDo: add param list to cache
|
||||||
//DebugLn('NOTE: TFindDeclarationTool.FindIdentifierInInterface Node is proc');
|
// -> do not cache
|
||||||
// ToDo: add param list to cache
|
|
||||||
// -> do not cache
|
|
||||||
Result:=false;
|
|
||||||
end else
|
|
||||||
FInterfaceIdentifierCache.Add(OldInput.Identifier,Params.NewNode,
|
|
||||||
Params.NewCleanPos);
|
|
||||||
end else begin
|
end else begin
|
||||||
// do not save proc identifiers or collection results
|
FInterfaceIdentifierCache.Add(OldInput.Identifier,Params.NewNode,
|
||||||
|
Params.NewCleanPos);
|
||||||
end;
|
end;
|
||||||
end else begin
|
end else begin
|
||||||
// identifier does not exist in this interface
|
// identifier does not exist in this interface
|
||||||
FInterfaceIdentifierCache.Add(OldInput.Identifier,nil,-1);
|
FInterfaceIdentifierCache.Add(OldInput.Identifier,nil,-1);
|
||||||
Result:=false;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -3684,8 +3684,7 @@ begin
|
|||||||
else
|
else
|
||||||
ExtractMemStream.Write(Src[LastAtomEndPos],
|
ExtractMemStream.Write(Src[LastAtomEndPos],
|
||||||
CurPos.StartPos-LastAtomEndPos);
|
CurPos.StartPos-LastAtomEndPos);
|
||||||
end else if (CurPos.StartPos>LastAtomEndPos)
|
end else if (ExtractMemStream.Position>0) then
|
||||||
and (ExtractMemStream.Position>0) then
|
|
||||||
begin
|
begin
|
||||||
// some code was skipped
|
// some code was skipped
|
||||||
// -> check if a space must be inserted
|
// -> check if a space must be inserted
|
||||||
|
@ -10530,6 +10530,12 @@ var
|
|||||||
NewUnitInfo: TUnitInfo;
|
NewUnitInfo: TUnitInfo;
|
||||||
begin
|
begin
|
||||||
Result:=mrCancel;
|
Result:=mrCancel;
|
||||||
|
if NewSource=nil then begin
|
||||||
|
DebugLn(['TMainIDE.DoJumpToCodePos ERROR: missing NewSource']);
|
||||||
|
DumpStack;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
if (ActiveSrcEdit=nil) or (ActiveUnitInfo=nil) then
|
if (ActiveSrcEdit=nil) or (ActiveUnitInfo=nil) then
|
||||||
GetCurrentUnit(ActiveSrcEdit,ActiveUnitInfo);
|
GetCurrentUnit(ActiveSrcEdit,ActiveUnitInfo);
|
||||||
if AddJumpPoint then begin
|
if AddJumpPoint then begin
|
||||||
@ -10554,7 +10560,7 @@ begin
|
|||||||
if NewY<1 then NewY:=1;
|
if NewY<1 then NewY:=1;
|
||||||
if NewTopLine<1 then
|
if NewTopLine<1 then
|
||||||
NewTopLine:=Max(1,NewY-(NewSrcEdit.EditorComponent.LinesInWindow div 2));
|
NewTopLine:=Max(1,NewY-(NewSrcEdit.EditorComponent.LinesInWindow div 2));
|
||||||
//writeln('[TMainIDE.DoJumpToCodePos] ',NewX,',',NewY,',',NewTopLine);
|
//debugln(['[TMainIDE.DoJumpToCodePos] ',NewX,',',NewY,',',NewTopLine]);
|
||||||
with NewSrcEdit.EditorComponent do begin
|
with NewSrcEdit.EditorComponent do begin
|
||||||
MoveLogicalCaretIgnoreEOL(Point(NewX,NewY));
|
MoveLogicalCaretIgnoreEOL(Point(NewX,NewY));
|
||||||
BlockBegin:=LogicalCaretXY;
|
BlockBegin:=LogicalCaretXY;
|
||||||
|
Loading…
Reference in New Issue
Block a user