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

View File

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

View File

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