IDE: Do not add assignment ':=' after a variable of procedure type. Issue #39545.

This commit is contained in:
Juha 2022-01-12 12:19:39 +02:00
parent 9cba2f5f48
commit 86c5fa6b45
3 changed files with 48 additions and 45 deletions

View File

@ -161,7 +161,7 @@ type
function IsPropertyReadOnly: boolean;
function GetHintModifiers: TPascalHintModifiers;
function CheckHasChilds: boolean;
function CanBeAssigned: boolean;
function CanBeAssigned(ADesc: TCodeTreeNodeDesc): boolean;
procedure UpdateBaseContext;
function HasChilds: boolean;
function HasIndex: boolean;
@ -4018,8 +4018,6 @@ var
ANode: TCodeTreeNode;
StartPos: Integer;
begin
Result:=(GetDesc=ctnProcedure);
if not Result then exit;
if (iliParamNameListValid in Flags) then begin
StartPos:=1;
while (StartPos<=length(FParamTypeList))
@ -4122,17 +4120,17 @@ begin
Result:=true;
end;
function TIdentifierListItem.CanBeAssigned: boolean;
function TIdentifierListItem.CanBeAssigned(ADesc: TCodeTreeNodeDesc): boolean;
var
ANode: TCodeTreeNode;
begin
Result:=false;
ANode:=Node;
if (ANode=nil) then exit;
if (GetDesc=ctnVarDefinition) then
Assert(Assigned(ANode), 'CanBeAssigned: Node=Nil');
if (ADesc=ctnVarDefinition) then
Result:=true;
if (ANode.Desc in [ctnProperty,ctnGlobalProperty]) then begin
if Tool.PropertyHasSpecifier(ANode,'write') then exit(true);
if (ADesc in [ctnProperty,ctnGlobalProperty]) then begin
if Tool.PropertyHasSpecifier(ANode,'WRITE') then exit(true);
if Tool.PropNodeIsTypeLess(ANode) then begin
exit(true);// ToDo: search the real property definition
end;

View File

@ -3349,27 +3349,37 @@ begin
end;
function TPascalReaderTool.ProcNodeHasParamList(ProcNode: TCodeTreeNode): boolean;
var
ChildNode: TCodeTreeNode;
begin
// ToDo: ppu, dcu
Result:=false;
if ProcNode=nil then exit;
if ProcNode.Desc=ctnProcedure then begin
ProcNode:=ProcNode.FirstChild;
if ProcNode=nil then exit;
ChildNode:=ProcNode.FirstChild;
// A variable of procedure type.
if (ProcNode.Desc=ctnVarDefinition)
and Assigned(ChildNode) and (ChildNode.Desc=ctnProcedureType) then
begin
ProcNode:=ChildNode.FirstChild; // ctnProcedureHead
if Assigned(ProcNode) then
ChildNode:=ProcNode.FirstChild; // There is no ctnParameterList. Why?
end
// Procedure
else if ProcNode.Desc=ctnProcedure then
ProcNode:=ChildNode;
if Assigned(ProcNode) and (ProcNode.Desc=ctnProcedureHead) then
begin
if Assigned(ChildNode) then
exit(ChildNode.Desc=ctnParameterList);
MoveCursorBehindProcName(ProcNode);
Result:=CurPos.Flag=cafRoundBracketOpen;
end;
if ProcNode.Desc<>ctnProcedureHead then exit;
if ProcNode.FirstChild<>nil then begin
Result:=ProcNode.FirstChild.Desc=ctnParameterList;
exit;
end;
MoveCursorBehindProcName(ProcNode);
Result:=CurPos.Flag=cafRoundBracketOpen;
end;
function TPascalReaderTool.ProcNodeHasOfObject(ProcNode: TCodeTreeNode
): boolean;
function TPascalReaderTool.ProcNodeHasOfObject(ProcNode: TCodeTreeNode): boolean;
begin
// ToDo: ppu, dcu

View File

@ -777,20 +777,15 @@ function GetIdentCompletionValue(aCompletion : TSynCompletion;
AddChar: TUTF8Char;
out ValueType: TIdentComplValue; out CursorToLeft: integer): string;
var
Index: Integer;
Index, ProcModifierPos, Indent: Integer;
IdentItem: TIdentifierListItem;
IdentList: TIdentifierList;
CursorAtEnd: boolean;
ProcModifierPos: LongInt;
CanAddSemicolon, CanAddComma, CursorAtEnd, IsReadOnly: boolean;
ProcHeadFlags: TProcHeadAttributes;
CanAddSemicolon: Boolean;
CanAddComma: Boolean;
ClassNode: TCodeTreeNode;
IsReadOnly: Boolean;
Line, s: string;
Indent: LongInt;
StartContextPos: TCodeXYPosition;
ClassNode: TCodeTreeNode; // For a class node or a procedure type node.
Dsc: TCodeTreeNodeDesc;
Line, s: string;
StartContextPos: TCodeXYPosition;
begin
Result:='';
CursorToLeft:=0;
@ -807,24 +802,26 @@ begin
IdentItem.BeautifyIdentifier(IdentList);
CodeToolBoss.IdentItemCheckHasChilds(IdentItem);
CanAddSemicolon:=CodeToolsOpts.IdentComplAddSemicolon and (AddChar<>';');
CanAddComma:=CodeToolsOpts.IdentComplAddSemicolon and (AddChar<>',');
IsReadOnly:=false;
Result:=IdentItem.Identifier;
Dsc:=IdentItem.GetDesc;
//DebugLn(['GetIdentCompletionValue IdentItem.GetDesc=',NodeDescriptionAsString(Dsc),
// ', IdentList.ContextFlags=',dbgs(IdentList.ContextFlags),' IdentItem.Node=',IdentItem.Node<>nil]);
if Dsc=ctnVarDefinition then begin
ClassNode:=IdentItem.Node.FirstChild;
if Assigned(ClassNode) and (ClassNode.Desc=ctnProcedureType) then
Dsc:=ctnProcedure;
end;
//debugln(['GetIdentCompletionValue IdentItem.GetDesc=',NodeDescriptionAsString(IdentItem.GetDesc),' IdentList.ContextFlags=',dbgs(IdentList.ContextFlags),' IdentItem.Node=',IdentItem.Node<>nil]);
case IdentItem.GetDesc of
case Dsc of
ctnProcedure:
begin
if (ilcfCanProcDeclaration in IdentList.ContextFlags)
and (IdentItem.Node<>nil) then begin
//DebugLn(['GetIdentCompletionValue icvCompleteProcDeclaration']);
ValueType:=icvCompleteProcDeclaration;
end else if IdentItem.IsProcNodeWithParams then
if (ilcfCanProcDeclaration in IdentList.ContextFlags) and (IdentItem.Node<>nil) then
ValueType:=icvCompleteProcDeclaration
else if IdentItem.IsProcNodeWithParams then
ValueType:=icvProcWithParams;
end;
@ -927,7 +924,7 @@ begin
and (not IsReadOnly)
and (not IdentList.StartUpAtomBehindIs(':='))
and (not IdentList.StartUpAtomBehindIs('('))
and (IdentItem.CanBeAssigned)
and (IdentItem.CanBeAssigned(Dsc))
and CodeToolsOpts.IdentComplAddAssignOperator then begin
if (atIdentifier in CodeToolsOpts.DoInsertSpaceAfter)
or (atSymbol in CodeToolsOpts.DoInsertSpaceInFront) then
@ -960,10 +957,8 @@ begin
// add semicolon for statement ends
//debugln(['GetIdentCompletionValue CanAddSemicolon=',CanAddSemicolon,' ilcfNoEndSemicolon=',ilcfNoEndSemicolon in IdentList.ContextFlags,' ']);
if CanAddSemicolon
and (not (ilcfNoEndSemicolon in IdentList.ContextFlags))
then begin
Dsc:=IdentItem.GetDesc;
if CanAddSemicolon and not (ilcfNoEndSemicolon in IdentList.ContextFlags) then
begin
if Dsc=ctnLabel then
Result+=':'
else