Skip to content

Commit d8a554a

Browse files
committed
Unparsing: refactor the handling of recurse_flatten nodes
Instead of storing the original node directly inside a document, keep track of this information locally during template instantiation. The design is clearer overall: it was strange to have a Node component in Document_Type that was sometimes null, sometimes with an actual node, which comes from the fact that there is no 1:1 mapping between nodes and document nodes, and some documents are created in contexts where it is not obvious for which node they are created. This is just a refactoring: no change of behavior intended.
1 parent 876b001 commit d8a554a

File tree

3 files changed

+82
-89
lines changed

3 files changed

+82
-89
lines changed

langkit/support/langkit_support-generic_api-unparsing.adb

Lines changed: 71 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -249,15 +249,28 @@ package body Langkit_Support.Generic_API.Unparsing is
249249
-- Node configurations for all node types in Language
250250
end record;
251251

252+
type Single_Template_Instantiation_Argument is record
253+
Document : Document_Type;
254+
-- Document to substitute to "recurse*" nodes when instantiating a
255+
-- template.
256+
257+
Node : Lk_Node;
258+
-- Node from which ``Document`` was generated. Keeping track of this is
259+
-- necessary in order to implement instantiation for "recurse_flatten".
260+
end record;
261+
262+
package Template_Instantiation_Arg_Vectors is new Ada.Containers.Vectors
263+
(Positive, Single_Template_Instantiation_Argument);
264+
252265
type Template_Instantiation_Args (Kind : Some_Template_Kind) is record
253266
case Kind is
254267
when With_Recurse | With_Text_Recurse =>
255-
With_Recurse_Doc : Document_Type;
268+
With_Recurse_Doc : Single_Template_Instantiation_Argument;
256269
-- Document to use in order to replace "recurse"/"recurse_flatten"
257270
-- templates.
258271

259272
when With_Recurse_Field =>
260-
Field_Docs : Document_Vectors.Vector;
273+
Field_Docs : Template_Instantiation_Arg_Vectors.Vector;
261274
-- Documents to use in order to replace "recurse_field" templates
262275
end case;
263276
end record;
@@ -1882,25 +1895,22 @@ package body Langkit_Support.Generic_API.Unparsing is
18821895
return Pool.Create_Align
18831896
(Template.Align_Data,
18841897
Instantiate_Template_Helper
1885-
(Pool, Node, Template.Align_Contents, Arguments),
1886-
Node);
1898+
(Pool, Node, Template.Align_Contents, Arguments));
18871899

18881900
when Break_Parent =>
18891901
return Pool.Create_Break_Parent;
18901902

18911903
when Fill =>
18921904
return Pool.Create_Fill
18931905
(Instantiate_Template_Helper
1894-
(Pool, Node, Template.Fill_Document, Arguments),
1895-
Node);
1906+
(Pool, Node, Template.Fill_Document, Arguments));
18961907

18971908
when Group =>
18981909
return Pool.Create_Group
18991910
(Instantiate_Template_Helper
19001911
(Pool, Node, Template.Group_Document, Arguments),
19011912
Template.Group_Should_Break,
1902-
Template.Group_Id,
1903-
Node);
1913+
Template.Group_Id);
19041914

19051915
when Hard_Line =>
19061916
return Pool.Create_Hard_Line;
@@ -1919,8 +1929,7 @@ package body Langkit_Support.Generic_API.Unparsing is
19191929
when Indent =>
19201930
return Pool.Create_Indent
19211931
(Instantiate_Template_Helper
1922-
(Pool, Node, Template.Indent_Document, Arguments),
1923-
Node);
1932+
(Pool, Node, Template.Indent_Document, Arguments));
19241933

19251934
when Line =>
19261935
return Pool.Create_Line;
@@ -1937,51 +1946,58 @@ package body Langkit_Support.Generic_API.Unparsing is
19371946
Template.List_Documents.Element (I),
19381947
Arguments));
19391948
end loop;
1940-
return Pool.Create_List (Items, Node);
1949+
return Pool.Create_List (Items);
19411950
end;
19421951

19431952
when Literal_Line =>
19441953
return Pool.Create_Literal_Line;
19451954

19461955
when Recurse =>
1947-
return Arguments.With_Recurse_Doc;
1956+
return Arguments.With_Recurse_Doc.Document;
19481957

19491958
when Recurse_Field =>
1950-
return Arguments.Field_Docs (Template.Recurse_Field_Position);
1959+
return Arguments
1960+
.Field_Docs (Template.Recurse_Field_Position)
1961+
.Document;
19511962

19521963
when Recurse_Flatten =>
1953-
return Result : Document_Type := Arguments.With_Recurse_Doc do
1964+
declare
1965+
Arg : constant Single_Template_Instantiation_Argument :=
1966+
Arguments.With_Recurse_Doc;
1967+
begin
1968+
return Result : Document_Type := Arg.Document do
19541969

1955-
-- As long as Result is a document we can flatten and that was
1956-
-- created by a node that passes the flattening guard, unwrap
1957-
-- it.
1970+
-- As long as Result is a document we can flatten and that
1971+
-- was created by a node that passes the flattening guard,
1972+
-- unwrap it.
19581973

1959-
while not Result.Node.Is_Null
1960-
and then Node_Matches
1961-
(Result.Node, Template.Recurse_Flatten_Types)
1962-
loop
1963-
case Result.Kind is
1964-
when Align =>
1965-
Result := Result.Align_Contents;
1974+
while not Arg.Node.Is_Null
1975+
and then Node_Matches
1976+
(Arg.Node, Template.Recurse_Flatten_Types)
1977+
loop
1978+
case Result.Kind is
1979+
when Align =>
1980+
Result := Result.Align_Contents;
19661981

1967-
when Fill =>
1968-
Result := Result.Fill_Document;
1982+
when Fill =>
1983+
Result := Result.Fill_Document;
19691984

1970-
when Group =>
1971-
Result := Result.Group_Document;
1985+
when Group =>
1986+
Result := Result.Group_Document;
19721987

1973-
when Indent =>
1974-
Result := Result.Indent_Document;
1988+
when Indent =>
1989+
Result := Result.Indent_Document;
19751990

1976-
when List =>
1977-
exit when Result.List_Documents.Length /= 1;
1978-
Result := Result.List_Documents.First_Element;
1991+
when List =>
1992+
exit when Result.List_Documents.Length /= 1;
1993+
Result := Result.List_Documents.First_Element;
19791994

1980-
when others =>
1981-
exit;
1982-
end case;
1983-
end loop;
1984-
end return;
1995+
when others =>
1996+
exit;
1997+
end case;
1998+
end loop;
1999+
end return;
2000+
end;
19852001

19862002
when Soft_Line =>
19872003
return Pool.Create_Soft_Line;
@@ -2083,7 +2099,8 @@ package body Langkit_Support.Generic_API.Unparsing is
20832099
declare
20842100
Args : constant Template_Instantiation_Args :=
20852101
(Kind => With_Recurse,
2086-
With_Recurse_Doc => Token);
2102+
With_Recurse_Doc =>
2103+
(Document => Token, Node => N));
20872104
begin
20882105
Token := Instantiate_Template
20892106
(Pool => Pool,
@@ -2123,7 +2140,11 @@ package body Langkit_Support.Generic_API.Unparsing is
21232140
(Pool => Pool,
21242141
Node => N,
21252142
Template => Template,
2126-
Arguments => (With_Recurse, Pool.Create_List (Items)));
2143+
Arguments =>
2144+
(Kind => With_Recurse,
2145+
With_Recurse_Doc =>
2146+
(Document => Pool.Create_List (Items),
2147+
Node => N)));
21272148

21282149
when With_Recurse_Field =>
21292150

@@ -2146,6 +2167,7 @@ package body Langkit_Support.Generic_API.Unparsing is
21462167
Child : constant Lk_Node := N.Child (I);
21472168
Field_Unparser : Field_Unparser_Impl renames
21482169
Node_Unparser.Field_Unparsers.Field_Unparsers (I);
2170+
Child_Doc : Document_Type;
21492171
begin
21502172
if Is_Field_Present (Child, Field_Unparser) then
21512173
Items.Clear;
@@ -2156,12 +2178,14 @@ package body Langkit_Support.Generic_API.Unparsing is
21562178
Field_Ref => Field_Unparser.Member,
21572179
Unparser => Field_Unparser,
21582180
Items => Items);
2159-
Arguments.Field_Docs.Append
2160-
(Pool.Create_List (Items));
2181+
Child_Doc := Pool.Create_List (Items);
21612182
else
2162-
Arguments.Field_Docs.Append
2163-
(Pool.Create_Empty_List);
2183+
Child_Doc := Pool.Create_Empty_List;
21642184
end if;
2185+
Arguments.Field_Docs.Append
2186+
(Single_Template_Instantiation_Argument'
2187+
(Document => Child_Doc,
2188+
Node => Child));
21652189
end;
21662190
end loop;
21672191

@@ -2207,7 +2231,9 @@ package body Langkit_Support.Generic_API.Unparsing is
22072231
Field_Template_Args : Template_Instantiation_Args
22082232
(Field_Template.Kind);
22092233
begin
2210-
Field_Template_Args.With_Recurse_Doc := Unparse_Node (Child);
2234+
Field_Template_Args.With_Recurse_Doc :=
2235+
(Document => Unparse_Node (Child),
2236+
Node => Child);
22112237

22122238
if Handle_Tokens then
22132239
Unparse_Tokens (Unparser.Pre_Tokens, Items);

0 commit comments

Comments
 (0)