Skip to content

Commit 50cdb69

Browse files
SA11-051 Avoid suggesting same code action multiple times
Move Named_Parameter refactoring logic to its own subprogram. Remove the while not Done logic from the Analyse_In_Context procedure, which was necessary only for the Named_Parameter code action.
1 parent 146a78f commit 50cdb69

File tree

2 files changed

+111
-121
lines changed

2 files changed

+111
-121
lines changed

source/ada/lsp-ada_handlers.adb

Lines changed: 109 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1246,8 +1246,7 @@ package body LSP.Ada_Handlers is
12461246
(Context : Context_Access;
12471247
Node : Libadalang.Analysis.Ada_Node;
12481248
Result : out LSP.Messages.CodeAction_Vector;
1249-
Found : in out Boolean;
1250-
Done : in out Boolean);
1249+
Found : in out Boolean);
12511250
-- Look for a possible refactoring in given Node.
12521251
-- Return Found = True if some refactoring is possible. Populate
12531252
-- Result with Code_Actions in this case. Return Done = True if futher
@@ -1257,14 +1256,6 @@ package body LSP.Ada_Handlers is
12571256
(Result : in out LSP.Messages.CodeAction_Vector);
12581257
-- Append project status code action if needed
12591258

1260-
Found_Named_Parameters : Boolean := False;
1261-
-- We propose only one choice of Named_Parameters refactoring per
1262-
-- request. So, if a user clicks on `1` in `A (B (1))` we propose the
1263-
-- refactoring for B (1), but not for A (...) call. We consider this
1264-
-- as better user experience.
1265-
--
1266-
-- This boolean filter to detect such refactoring duplication.
1267-
12681259
----------------------------------
12691260
-- Has_Assoc_Without_Designator --
12701261
----------------------------------
@@ -1401,12 +1392,8 @@ package body LSP.Ada_Handlers is
14011392
(Context : Context_Access;
14021393
Node : Libadalang.Analysis.Ada_Node;
14031394
Result : out LSP.Messages.CodeAction_Vector;
1404-
Found : in out Boolean;
1405-
Done : in out Boolean)
1395+
Found : in out Boolean)
14061396
is
1407-
procedure Append_Command (Node : Libadalang.Analysis.Ada_Node);
1408-
-- Contruct a command and append it to Result
1409-
14101397
procedure Change_Parameters_Type_Code_Action;
14111398
-- Checks if the Change Parameters Type refactoring tool is avaiable,
14121399
-- and if so, appends a Code Action with its Command.
@@ -1423,50 +1410,14 @@ package body LSP.Ada_Handlers is
14231410
-- Checks if the Introduce Parameter refactoring tool is available,
14241411
-- and if so, appends a Code Action with its Command.
14251412

1413+
procedure Named_Parameters_Code_Action;
1414+
-- Checks if the Named Parameters refactoring is available, and if
1415+
-- so, appends a Code Action with its Command.
1416+
14261417
procedure Pull_Up_Declaration_Code_Action;
14271418
-- Checks if the Pull Up Declaration refactoring tool is available,
14281419
-- and if so, appends a Code Action with its Command.
14291420

1430-
--------------------
1431-
-- Append_Command --
1432-
--------------------
1433-
1434-
procedure Append_Command (Node : Libadalang.Analysis.Ada_Node) is
1435-
Command : LSP.Ada_Handlers.Named_Parameters_Commands.Command;
1436-
Pointer : LSP.Commands.Command_Pointer;
1437-
Item : LSP.Messages.CodeAction;
1438-
Where : constant LSP.Messages.Location :=
1439-
LSP.Lal_Utils.Get_Node_Location (Node);
1440-
begin
1441-
if Found_Named_Parameters then
1442-
return;
1443-
end if;
1444-
1445-
Command.Initialize
1446-
(Context => Context.all,
1447-
Where => ((uri => Where.uri), Where.span.first));
1448-
1449-
Pointer.Set (Command);
1450-
1451-
Item :=
1452-
(title => "Name parameters in the call",
1453-
kind => (Is_Set => True,
1454-
Value => LSP.Messages.RefactorRewrite),
1455-
diagnostics => (Is_Set => False),
1456-
disabled => (Is_Set => False),
1457-
edit => (Is_Set => False),
1458-
isPreferred => (Is_Set => False),
1459-
command => (Is_Set => True,
1460-
Value =>
1461-
(Is_Unknown => False,
1462-
title => <>,
1463-
Custom => Pointer)));
1464-
1465-
Result.Append (Item);
1466-
Found := True;
1467-
Found_Named_Parameters := True;
1468-
end Append_Command;
1469-
14701421
----------------------------------------
14711422
-- Change_Parameters_Type_Code_Action --
14721423
----------------------------------------
@@ -1500,6 +1451,8 @@ package body LSP.Ada_Handlers is
15001451
span => Params.span,
15011452
alsKind => LSP.Messages.Empty_Set),
15021453
Syntax_Rules => Syntax_Rules);
1454+
1455+
Found := True;
15031456
end if;
15041457
end Change_Parameters_Type_Code_Action;
15051458

@@ -1533,6 +1486,8 @@ package body LSP.Ada_Handlers is
15331486
(uri => Params.textDocument.uri,
15341487
span => Params.span,
15351488
alsKind => LSP.Messages.Empty_Set));
1489+
1490+
Found := True;
15361491
end if;
15371492
end Change_Parameters_Default_Value_Code_Action;
15381493

@@ -1591,7 +1546,6 @@ package body LSP.Ada_Handlers is
15911546
end if;
15921547

15931548
Found := True;
1594-
Done := True;
15951549
end if;
15961550
end if;
15971551
end Extract_Subprogram_Code_Action;
@@ -1625,9 +1579,104 @@ package body LSP.Ada_Handlers is
16251579
(uri => Params.textDocument.uri,
16261580
span => Params.span,
16271581
alsKind => LSP.Messages.Empty_Set));
1582+
1583+
Found := True;
16281584
end if;
16291585
end Introduce_Parameter_Code_Action;
16301586

1587+
----------------------------------
1588+
-- Named_Parameters_Code_Action --
1589+
----------------------------------
1590+
1591+
procedure Named_Parameters_Code_Action is
1592+
Aux_Node : Libadalang.Analysis.Ada_Node := Node;
1593+
Done : Boolean := False;
1594+
-- We propose only one choice of Named_Parameters refactoring per
1595+
-- request. So, if a user clicks on `1` in `A (B (1))` we propose
1596+
-- the refactoring for B (1), but not for A (...) call. We
1597+
-- consider this as better user experience.
1598+
--
1599+
-- This boolean filter to detect such refactoring duplication.
1600+
1601+
procedure Append_Command (Node : Libadalang.Analysis.Ada_Node);
1602+
-- Contruct a command and append it to Result
1603+
1604+
--------------------
1605+
-- Append_Command --
1606+
--------------------
1607+
1608+
procedure Append_Command (Node : Libadalang.Analysis.Ada_Node) is
1609+
Command : LSP.Ada_Handlers.Named_Parameters_Commands.Command;
1610+
Pointer : LSP.Commands.Command_Pointer;
1611+
Item : LSP.Messages.CodeAction;
1612+
Where : constant LSP.Messages.Location :=
1613+
LSP.Lal_Utils.Get_Node_Location (Node);
1614+
1615+
begin
1616+
Command.Initialize
1617+
(Context => Context.all,
1618+
Where => ((uri => Where.uri), Where.span.first));
1619+
1620+
Pointer.Set (Command);
1621+
1622+
Item :=
1623+
(title => "Name parameters in the call",
1624+
kind => (Is_Set => True,
1625+
Value => LSP.Messages.RefactorRewrite),
1626+
diagnostics => (Is_Set => False),
1627+
disabled => (Is_Set => False),
1628+
edit => (Is_Set => False),
1629+
isPreferred => (Is_Set => False),
1630+
command => (Is_Set => True,
1631+
Value =>
1632+
(Is_Unknown => False,
1633+
title => <>,
1634+
Custom => Pointer)));
1635+
1636+
Result.Append (Item);
1637+
1638+
Done := True;
1639+
Found := True;
1640+
end Append_Command;
1641+
1642+
begin
1643+
while not Done and then not Aux_Node.Is_Null loop
1644+
case Aux_Node.Kind is
1645+
when Libadalang.Common.Ada_Stmt
1646+
| Libadalang.Common.Ada_Basic_Decl =>
1647+
1648+
Done := True;
1649+
1650+
when Libadalang.Common.Ada_Basic_Assoc_List =>
1651+
if Has_Assoc_Without_Designator
1652+
(Aux_Node.As_Basic_Assoc_List)
1653+
then
1654+
Append_Command (Aux_Node);
1655+
end if;
1656+
1657+
when Libadalang.Common.Ada_Call_Expr =>
1658+
declare
1659+
List : constant Libadalang.Analysis.Ada_Node :=
1660+
Aux_Node.As_Call_Expr.F_Suffix;
1661+
1662+
begin
1663+
if not List.Is_Null
1664+
and then List.Kind in
1665+
Libadalang.Common.Ada_Basic_Assoc_List
1666+
and then Has_Assoc_Without_Designator
1667+
(List.As_Basic_Assoc_List)
1668+
then
1669+
Append_Command (List);
1670+
end if;
1671+
end;
1672+
when others =>
1673+
null;
1674+
end case;
1675+
1676+
Aux_Node := Aux_Node.Parent;
1677+
end loop;
1678+
end Named_Parameters_Code_Action;
1679+
16311680
-------------------------------------
16321681
-- Pull_Up_Declaration_Code_Action --
16331682
-------------------------------------
@@ -1664,39 +1713,15 @@ package body LSP.Ada_Handlers is
16641713
alsKind => Empty_Set));
16651714

16661715
Found := True;
1667-
Done := True;
16681716
end if;
16691717
end Pull_Up_Declaration_Code_Action;
16701718

16711719
Kind : constant Libadalang.Common.Ada_Node_Kind_Type := Node.Kind;
16721720

16731721
begin
1674-
case Kind is
1675-
when Libadalang.Common.Ada_Stmt
1676-
| Libadalang.Common.Ada_Basic_Decl =>
1677-
1678-
Done := True;
1679-
1680-
when Libadalang.Common.Ada_Basic_Assoc_List =>
1681-
if Has_Assoc_Without_Designator (Node.As_Basic_Assoc_List) then
1682-
Append_Command (Node);
1683-
end if;
1684-
1685-
when Libadalang.Common.Ada_Call_Expr =>
1686-
declare
1687-
List : constant Libadalang.Analysis.Ada_Node :=
1688-
Node.As_Call_Expr.F_Suffix;
1689-
begin
1690-
if not List.Is_Null
1691-
and then List.Kind in
1692-
Libadalang.Common.Ada_Basic_Assoc_List
1693-
and then Has_Assoc_Without_Designator
1694-
(List.As_Basic_Assoc_List)
1695-
then
1696-
Append_Command (List);
1697-
end if;
1698-
end;
1722+
Named_Parameters_Code_Action;
16991723

1724+
case Kind is
17001725
when Libadalang.Common.Ada_Identifier =>
17011726
declare
17021727
Name : constant Libadalang.Analysis.Name
@@ -1837,7 +1862,6 @@ package body LSP.Ada_Handlers is
18371862
Requires_Full_Specification);
18381863

18391864
Found := True;
1840-
Done := True;
18411865
end if;
18421866
end;
18431867
end if;
@@ -1878,7 +1902,6 @@ package body LSP.Ada_Handlers is
18781902
Parameters_Indices => Parameter_Indices_Range);
18791903

18801904
Found := True;
1881-
Done := True;
18821905
end if;
18831906
end;
18841907

@@ -1909,7 +1932,6 @@ package body LSP.Ada_Handlers is
19091932
end loop;
19101933

19111934
Found := True;
1912-
Done := True;
19131935
end if;
19141936
end;
19151937

@@ -1938,7 +1960,6 @@ package body LSP.Ada_Handlers is
19381960
end loop;
19391961

19401962
Found := True;
1941-
Done := True;
19421963
end if;
19431964
end;
19441965

@@ -1961,7 +1982,6 @@ package body LSP.Ada_Handlers is
19611982
Target_Separate => Target_Separate);
19621983

19631984
Found := True;
1964-
Done := True;
19651985
end if;
19661986
end;
19671987
end Analyse_Node;
@@ -1976,14 +1996,10 @@ package body LSP.Ada_Handlers is
19761996
Result : out LSP.Messages.CodeAction_Vector;
19771997
Found : in out Boolean)
19781998
is
1979-
Done : Boolean := False; -- True when futher analysis has no sense
1980-
Node : Libadalang.Analysis.Ada_Node :=
1999+
Node : constant Libadalang.Analysis.Ada_Node :=
19812000
Document.Get_Node_At (Context.all, Params.span.first);
19822001
begin
1983-
while not Done and then not Node.Is_Null loop
1984-
Analyse_Node (Context, Node, Result, Found, Done);
1985-
Node := Node.Parent;
1986-
end loop;
2002+
Analyse_Node (Context, Node, Result, Found);
19872003
end Analyse_In_Context;
19882004

19892005
---------------------------

testsuite/ada_lsp/refactoring_introduce_parameter/SA11-051/test.json

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -183,33 +183,7 @@
183183
{
184184
"id": 2,
185185
"result": [
186-
{
187-
"title": "Extract Procedure",
188-
"kind": "refactor.extract",
189-
"command": {
190-
"title": "",
191-
"command": "als-refactor-extract-subprogram",
192-
"arguments": [
193-
{
194-
"context_id": "Default",
195-
"section_to_extract_sloc": {
196-
"uri": "$URI{main.adb}",
197-
"range": {
198-
"start": {
199-
"line": 4,
200-
"character": 33
201-
},
202-
"end": {
203-
"line": 4,
204-
"character": 46
205-
}
206-
}
207-
},
208-
"subprogram_kind": "ADA_SUBP_KIND_PROCEDURE"
209-
}
210-
]
211-
}
212-
},
186+
"<HAS>",
213187
{
214188
"title": "Introduce Parameter",
215189
"kind": "refactor.rewrite",
@@ -350,4 +324,4 @@
350324
"exit_code": 0
351325
}
352326
}
353-
]
327+
]

0 commit comments

Comments
 (0)