File 1173-syntax_tools-Improve-reverting-lists.patch of Package erlang

From b4bc274accd4e8a24d32509e7b596e44b82d3024 Mon Sep 17 00:00:00 2001
From: Richard Carlsson <carlsson.richard@gmail.com>
Date: Wed, 1 Jan 2025 16:44:22 +0100
Subject: [PATCH 3/4] syntax_tools: Improve reverting lists.

Avoids copying other annotations than location onto the cons nodes.
Propagates correct end information to the nil node if available, and
if not, avoids setting a wrong location for the nil.
---
 lib/syntax_tools/src/erl_syntax.erl | 43 ++++++++++++++++++++---------
 1 file changed, 30 insertions(+), 13 deletions(-)

diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl
index 930e1c6307..bf1acc81d4 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -2455,22 +2455,39 @@ list(Elements, Tail) when Elements =/= [] ->
 revert_list(Node) ->
     Pos = get_pos(Node),
     Prefix = list_prefix(Node),
-    Suffix = case list_suffix(Node) of
+    Suffix =
+        case list_suffix(Node) of
 	    none ->
-            LastPos = get_pos(lists:last(Prefix)),
-            LastLocation = case erl_anno:end_location(LastPos) of
-                undefined -> erl_anno:location(LastPos);
-                Location -> Location
-            end,
-            revert_nil(set_pos(nil(), erl_anno:set_location(LastLocation, Pos)));
+                %% there is no explicit `| Tail]` part, just a plain list
+                %% `[X1,...XN]`, so we must invent a nil node
+                case erl_anno:end_location(Pos) of
+                    undefined ->
+                        LastPos = get_pos(lists:last(Prefix)),
+                        case erl_anno:end_location(LastPos) of
+                            undefined ->
+                                %% use a zero location rather than a wrong one
+                                {nil, erl_anno:new(0)};
+                            EndLoc ->
+                                %% if the last element has an end location,
+                                %% we take that as both start and end
+                                {nil, erl_anno:set_end_location(EndLoc, erl_anno:new(EndLoc))}
+                        end;
+                    EndLoc ->
+                        %% if the whole list node has an end location, we
+                        %% take that as both start and end of the nil
+                        {nil, erl_anno:set_end_location(EndLoc, erl_anno:new(EndLoc))}
+                end;
 	    Suffix1 ->
-            Suffix1
+                Suffix1
 	end,
-    lists:foldr(fun (Head, Tail) ->
-        HeadPos = get_pos(Head),
-        HeadLocation = erl_anno:location(HeadPos),
-        {cons, erl_anno:set_location(HeadLocation, Pos), Head, Tail}
-    end, Suffix, Prefix).
+    F = fun (Head, Tail) ->
+                %% the nested conses get the location from the list
+                %% elements, but other annotations must not be copied
+                HeadLoc = erl_anno:location(get_pos(Head)),
+                {cons, erl_anno:new(HeadLoc), Head, Tail}
+        end,
+    %% the outermost cons gets the full annotations of the list
+    setelement(2, lists:foldr(F, Suffix, Prefix), Pos).
 
 %% =====================================================================
 %% @doc Creates an abstract empty list. The result represents
-- 
2.43.0

openSUSE Build Service is sponsored by