mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-15 05:59:30 +02:00
codetools: code completion: completing class interface properties
git-svn-id: trunk@13338 -
This commit is contained in:
parent
e26fc219ae
commit
b9e3bc84b4
@ -92,8 +92,11 @@ type
|
|||||||
TNewVarLocation = (
|
TNewVarLocation = (
|
||||||
ncpvPrivate,ncpvProtected,ncpvPublic,ncpvPublished,ncpvLocal
|
ncpvPrivate,ncpvProtected,ncpvPublic,ncpvPublished,ncpvLocal
|
||||||
);
|
);
|
||||||
|
|
||||||
const
|
const
|
||||||
|
NewClassPartProcs = [ncpPrivateProcs,ncpProtectedProcs,ncpPublicProcs,ncpPublishedProcs];
|
||||||
|
NewClassPartVars = [ncpPrivateVars,ncpProtectedVars,ncpPublicVars,ncpPublishedVars];
|
||||||
|
|
||||||
NewClassPartVisibilty: array[TNewClassPart] of TPascalClassSection = (
|
NewClassPartVisibilty: array[TNewClassPart] of TPascalClassSection = (
|
||||||
pcsPrivate, pcsPrivate,
|
pcsPrivate, pcsPrivate,
|
||||||
pcsProtected, pcsProtected,
|
pcsProtected, pcsProtected,
|
||||||
@ -393,6 +396,14 @@ begin
|
|||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DebugLn('[TCodeCompletionCodeTool.AddClassInsertion] CleanDef="',CleanDef,'" Def="',Def,'" Identifiername="',Identifiername,'" Body="',Body,'"');
|
DebugLn('[TCodeCompletionCodeTool.AddClassInsertion] CleanDef="',CleanDef,'" Def="',Def,'" Identifiername="',Identifiername,'" Body="',Body,'"');
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
if FCodeCompleteClassNode.Desc=ctnClassInterface then begin
|
||||||
|
// a class interface has no section -> put them all into 'public'
|
||||||
|
if TheType in NewClassPartProcs then
|
||||||
|
TheType:=ncpPublicProcs
|
||||||
|
else if TheType in NewClassPartVars then
|
||||||
|
raise Exception.Create('TCodeCompletionCodeTool.AddClassInsertion can not add variables to a class interface');
|
||||||
|
end;
|
||||||
|
|
||||||
NewInsert:=NodeExtMemManager.NewNode;
|
NewInsert:=NodeExtMemManager.NewNode;
|
||||||
with NewInsert do begin
|
with NewInsert do begin
|
||||||
Node:=PosNode;
|
Node:=PosNode;
|
||||||
@ -3791,12 +3802,14 @@ var AccessParam, AccessParamPrefix, CleanAccessFunc, AccessFunc,
|
|||||||
|
|
||||||
// check if read access variable exists
|
// check if read access variable exists
|
||||||
if (Parts[ppParamList].StartPos<1) and (Parts[ppIndexWord].StartPos<1)
|
if (Parts[ppParamList].StartPos<1) and (Parts[ppIndexWord].StartPos<1)
|
||||||
|
and (FCodeCompleteClassNode.Desc<>ctnClassInterface)
|
||||||
and VarExistsInCodeCompleteClass(UpperCaseStr(AccessParam)) then exit;
|
and VarExistsInCodeCompleteClass(UpperCaseStr(AccessParam)) then exit;
|
||||||
|
|
||||||
// complete read access specifier
|
// complete read access specifier
|
||||||
if (Parts[ppParamList].StartPos>0) or (Parts[ppIndexWord].StartPos>0)
|
if (Parts[ppParamList].StartPos>0) or (Parts[ppIndexWord].StartPos>0)
|
||||||
or (SysUtils.CompareText(AccessParamPrefix,
|
or (SysUtils.CompareText(AccessParamPrefix,
|
||||||
LeftStr(AccessParam,length(AccessParamPrefix)))=0) then
|
LeftStr(AccessParam,length(AccessParamPrefix)))=0)
|
||||||
|
or (FCodeCompleteClassNode.Desc=ctnClassInterface) then
|
||||||
begin
|
begin
|
||||||
// the read identifier is a function
|
// the read identifier is a function
|
||||||
{$IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
@ -3919,12 +3932,14 @@ var AccessParam, AccessParamPrefix, CleanAccessFunc, AccessFunc,
|
|||||||
|
|
||||||
// check if write variable exists
|
// check if write variable exists
|
||||||
if (Parts[ppParamList].StartPos<1) and (Parts[ppIndexWord].StartPos<1)
|
if (Parts[ppParamList].StartPos<1) and (Parts[ppIndexWord].StartPos<1)
|
||||||
|
and (FCodeCompleteClassNode.Desc<>ctnClassInterface)
|
||||||
and VarExistsInCodeCompleteClass(UpperCaseStr(AccessParam)) then exit;
|
and VarExistsInCodeCompleteClass(UpperCaseStr(AccessParam)) then exit;
|
||||||
|
|
||||||
// complete class
|
// complete class
|
||||||
if (Parts[ppParamList].StartPos>0) or (Parts[ppIndexWord].StartPos>0)
|
if (Parts[ppParamList].StartPos>0) or (Parts[ppIndexWord].StartPos>0)
|
||||||
or (SysUtils.CompareText(AccessParamPrefix,
|
or (SysUtils.CompareText(AccessParamPrefix,
|
||||||
LeftStr(AccessParam,length(AccessParamPrefix)))=0) then
|
LeftStr(AccessParam,length(AccessParamPrefix)))=0)
|
||||||
|
or (FCodeCompleteClassNode.Desc=ctnClassInterface) then
|
||||||
begin
|
begin
|
||||||
// add insert demand for function
|
// add insert demand for function
|
||||||
// build function code
|
// build function code
|
||||||
@ -4107,10 +4122,14 @@ begin
|
|||||||
ClassSectionNode:=ClassSectionNode.NextBrother;
|
ClassSectionNode:=ClassSectionNode.NextBrother;
|
||||||
end else if ANodeExt.Node<>nil then begin
|
end else if ANodeExt.Node<>nil then begin
|
||||||
// search a section of the same Visibility in front of the node
|
// search a section of the same Visibility in front of the node
|
||||||
ClassSectionNode:=ANodeExt.Node.Parent.PriorBrother;
|
if FCodeCompleteClassNode.Desc=ctnClass then begin
|
||||||
while (ClassSectionNode<>nil)
|
ClassSectionNode:=ANodeExt.Node.Parent.PriorBrother;
|
||||||
and (ClassSectionNode.Desc<>ClassSectionNodeType[Visibility]) do
|
while (ClassSectionNode<>nil)
|
||||||
ClassSectionNode:=ClassSectionNode.PriorBrother;
|
and (ClassSectionNode.Desc<>ClassSectionNodeType[Visibility]) do
|
||||||
|
ClassSectionNode:=ClassSectionNode.PriorBrother;
|
||||||
|
end else begin
|
||||||
|
ClassSectionNode:=FCodeCompleteClassNode;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
if ClassSectionNode=nil then begin
|
if ClassSectionNode=nil then begin
|
||||||
// there is no existing class section node
|
// there is no existing class section node
|
||||||
@ -4126,7 +4145,7 @@ begin
|
|||||||
// nil means insert as first
|
// nil means insert as first
|
||||||
InsertBehind:=true;
|
InsertBehind:=true;
|
||||||
ANode:=ClassSectionNode.FirstChild;
|
ANode:=ClassSectionNode.FirstChild;
|
||||||
|
|
||||||
// skip the class GUID
|
// skip the class GUID
|
||||||
if (ANode<>nil) and (ANode.Desc=ctnClassGUID) then
|
if (ANode<>nil) and (ANode.Desc=ctnClassGUID) then
|
||||||
ANode:=ANode.NextBrother;
|
ANode:=ANode.NextBrother;
|
||||||
@ -4226,7 +4245,22 @@ begin
|
|||||||
// insert as first variable/proc
|
// insert as first variable/proc
|
||||||
Indent:=GetLineIndent(Src,ClassSectionNode.StartPos)
|
Indent:=GetLineIndent(Src,ClassSectionNode.StartPos)
|
||||||
+ASourceChangeCache.BeautifyCodeOptions.Indent;
|
+ASourceChangeCache.BeautifyCodeOptions.Indent;
|
||||||
InsertPos:=FindLineEndOrCodeAfterPosition(ClassSectionNode.StartPos);
|
InsertPos:=ClassSectionNode.StartPos;
|
||||||
|
if (ClassSectionNode.Desc in AllClassBaseSections)
|
||||||
|
or (ClassSectionNode.Desc in AllClassTypeSections) then begin
|
||||||
|
// skip keyword
|
||||||
|
inc(InsertPos,GetIdentLen(@Src[InsertPos]));
|
||||||
|
end else if ClassSectionNode.Desc=ctnClassInterface then begin
|
||||||
|
// skip class interface header
|
||||||
|
MoveCursorToCleanPos(InsertPos);
|
||||||
|
ReadNextAtom; // skip 'interface'
|
||||||
|
InsertPos:=CurPos.EndPos;
|
||||||
|
if ReadNextAtomIsChar('(') then begin
|
||||||
|
ReadTilBracketClose(true);
|
||||||
|
InsertPos:=CurPos.EndPos;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
InsertPos:=FindLineEndOrCodeAfterPosition(InsertPos);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
CurCode:=ANodeExt.ExtTxt1;
|
CurCode:=ANodeExt.ExtTxt1;
|
||||||
@ -4291,6 +4325,11 @@ var
|
|||||||
SectionKeyWord: String;
|
SectionKeyWord: String;
|
||||||
ANode: TCodeTreeNode;
|
ANode: TCodeTreeNode;
|
||||||
begin
|
begin
|
||||||
|
if FCodeCompleteClassNode.Desc=ctnClassInterface then begin
|
||||||
|
// a class interface has no sections
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
NewClassSectionInsertPos[Visibility]:=-1;
|
NewClassSectionInsertPos[Visibility]:=-1;
|
||||||
NewClassSectionIndent[Visibility]:=0;
|
NewClassSectionIndent[Visibility]:=0;
|
||||||
if GetFirstNodeExtWithVisibility(Visibility)=nil then exit;
|
if GetFirstNodeExtWithVisibility(Visibility)=nil then exit;
|
||||||
@ -5121,15 +5160,16 @@ var CleanCursorPos, Indent, insertPos: integer;
|
|||||||
// go through all properties and procs
|
// go through all properties and procs
|
||||||
// insert read + write prop specifiers
|
// insert read + write prop specifiers
|
||||||
// demand Variables + Procs + Proc Bodies
|
// demand Variables + Procs + Proc Bodies
|
||||||
{ $IFDEF CTDEBUG}
|
{$IFDEF CTDEBUG}
|
||||||
DebugLn('TCodeCompletionCodeTool.CompleteCode Complete Properties ... ');
|
DebugLn('TCodeCompletionCodeTool.CompleteCode Complete Properties ... ');
|
||||||
{ $ENDIF}
|
{$ENDIF}
|
||||||
SectionNode:=FCodeCompleteClassNode.FirstChild;
|
if FCodeCompleteClassNode.Desc=ctnClass then
|
||||||
|
SectionNode:=FCodeCompleteClassNode.FirstChild
|
||||||
|
else
|
||||||
|
SectionNode:=FCodeCompleteClassNode;
|
||||||
while SectionNode<>nil do begin
|
while SectionNode<>nil do begin
|
||||||
//DebugLn(['CompleteClass AAA1']);
|
|
||||||
ANode:=SectionNode.FirstChild;
|
ANode:=SectionNode.FirstChild;
|
||||||
while ANode<>nil do begin
|
while ANode<>nil do begin
|
||||||
//DebugLn(['CompleteClass AAA2 ',ANode.DescAsString]);
|
|
||||||
if ANode.Desc=ctnProperty then begin
|
if ANode.Desc=ctnProperty then begin
|
||||||
// check if property is complete
|
// check if property is complete
|
||||||
if not CompleteProperty(ANode) then
|
if not CompleteProperty(ANode) then
|
||||||
@ -5137,6 +5177,7 @@ var CleanCursorPos, Indent, insertPos: integer;
|
|||||||
end;
|
end;
|
||||||
ANode:=ANode.NextBrother;
|
ANode:=ANode.NextBrother;
|
||||||
end;
|
end;
|
||||||
|
if SectionNode=FCodeCompleteClassNode then break;
|
||||||
SectionNode:=SectionNode.NextBrother;
|
SectionNode:=SectionNode.NextBrother;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -3219,7 +3219,7 @@ begin
|
|||||||
SaveRaiseExceptionFmt(ctsNestedDefinitionsAreNotAllowed,['interface']);
|
SaveRaiseExceptionFmt(ctsNestedDefinitionsAreNotAllowed,['interface']);
|
||||||
IntfAtomPos:=CurPos;
|
IntfAtomPos:=CurPos;
|
||||||
// class interface start found
|
// class interface start found
|
||||||
ChildCreated:=true;
|
ChildCreated:=true; // maybe change this in future to jit parsing
|
||||||
if ChildCreated then begin
|
if ChildCreated then begin
|
||||||
CreateChildNode;
|
CreateChildNode;
|
||||||
CurNode.Desc:=ctnClassInterface;
|
CurNode.Desc:=ctnClassInterface;
|
||||||
|
Loading…
Reference in New Issue
Block a user