4.3. Configuration snippets examples
4.3.1. ArrayTypeDef rewrite to enforce vertical formatting
This configuration snippet illustrates ArrayTypeDef node rewriting to enforce
the formatting of the array type declaration “vertically”, e.g. for multidimensional arrays,
each index_subtype_definition or discrete_subtype_definition goes on a separate line.
To achieve this, the rewritting will override the ConstraintList and
UnconstrainedArrayIndexList of the ArrayTypeDef node.
Input code
Consider the following code snippet:
package ArrayTypeDef is
type Constrained_Matrix is
array (Natural range 0 .. L1, Natural range 0 .. L2, Natural range 0 .. L3)
of Integer;
type Unconstrained_Matrix is array(Integer range <>, Integer range <>) of Real;
end ArrayTypeDef;
Expected output code
The desired layout is structured as follows:
package ArrayTypeDef is
type Constrained_Matrix is
array (Natural range 0 .. L1,
Natural range 0 .. L2,
Natural range 0 .. L3)
of Integer;
type Unconstrained_Matrix is
array (Integer range <>,
Integer range <>)
of Real;
end ArrayTypeDef;
Configuration snippet
This result is obtained using the following custom configuration:
{
"node_configs": {
"ConstraintList": {
"sep": [
"recurse",
"hardline"
],
"table": null
},
"UnconstrainedArrayIndexList": {
"sep": [
"recurse",
"hardline"
]
}
}
}
Note
This configuration snippet produces the same result as the gnatpp
--vertical-array-types switch.
4.3.2. CaseStmt, CaseExpr and VariantPart rewrite to enforce vertical alternatives
This configuration snippet illustrates AlternativesList node rewriting to enforce
the vertical formatting in CaseStmt, CaseExpr and VariantPart by forcing
every | choice to break onto a new line regardless of whether it appears in
a case statement, case expression or record variant part.
Input code
Consider the following code snippet:
procedure Vertical_Alternatives is
-- CaseExpr alternatives
Status_Str : constant String :=
(case Current_Status is
when Idle | Ready | Waiting => "Standby",
when Running | Processing => "Active",
when Fault | Error => "Failed");
-- VariantPart alternatives
type Sensor_Status (Kind : Sensor_Kind) is record
case Kind is
when Temperature | Humidity | Pressure => Reading : Float;
when Discrete | Binary => State : Boolean;
when others => Raw_Value : Integer;
end case;
end record;
begin
-- CaseSmt alternatives
case Current_State is
when Idle | Waiting | Suspended => Process_Idle;
when Active | Running => Process_Active;
when others => Process_Unknown;
end case;
end Vertical_Alternatives;
Expected output code
The desired layout is structured as follows:
procedure Vertical_Alternatives is
-- CaseExpr alternatives
Status_Str : constant String :=
(case Current_Status is
when Idle
| Ready
| Waiting => "Standby",
when Running
| Processing => "Active",
when Fault
| Error => "Failed");
-- VariantPart alternatives
type Sensor_Status (Kind : Sensor_Kind) is record
case Kind is
when Temperature
| Humidity
| Pressure
=>
Reading : Float;
when Discrete
| Binary
=>
State : Boolean;
when others =>
Raw_Value : Integer;
end case;
end record;
begin
-- CaseSmt alternatives
case Current_State is
when Idle
| Waiting
| Suspended =>
Process_Idle;
when Active
| Running =>
Process_Active;
when others =>
Process_Unknown;
end case;
end Vertical_Alternatives;
Configuration snippet
This result is obtained using the following custom configuration:
{
"node_configs": {
"AlternativesList": {
"sep": [
"hardline",
"recurse",
"whitespace"
],
"table": null
}
}
}
Note
This configuration snippet produces the same result as the gnatpp
--vertical-case-alternatives switch.
4.3.3. EnumTypeDef rewrite to enforce vertical formatting
This configuration snippet illustrates EnumTypeDef node rewriting to enforce
the formatting of the enumeration type declaration “vertically”, e.g. each
enumeration literal goes on a separate line. To achieve this, the rewritting will
override the EnumLiteralDeclList of the EnumTypeDef node.
Input code
Consider the following code snippet:
type Day is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
Expected output code
The desired layout is structured as follows:
type Day is
(Mon,
Tue,
Wed,
Thu,
Fri,
Sat,
Sun);
Configuration snippet
This result is obtained using the following custom configuration:
{
"node_configs": {
"EnumLiteralDeclList": {
"sep": [
"recurse",
"hardline"
]
}
}
}
Note
This configuration snippet produces the same result as the gnatpp
--vertical-enum-types switch.
4.3.4. IfStmt rewrite to place then on a separate line
This configuration snippet illustrates IfStmt and ElsifStmtPart nodes
rewriting to enforce a line break before the then keyword. This will place
the keyword then in IF statements on a separate line.
Input code
Consider the following code snippet:
if Foo then
null;
elsif Bar then
null;
elsif Baz then
null;
else
null;
end if;
Expected output code
The desired layout is structured as follows:
if Foo
then
null;
elsif Bar
then
null;
elsif Baz
then
null;
else
null;
end if;
Configuration snippet
This result is obtained using the following custom configuration:
{
"node_configs": {
"ElsifStmtPart": {
"node": {
"kind": "group",
"document": [
{
"kind": "group",
"document": [
{
"kind": "text",
"text": "elsif"
},
"whitespace",
{
"kind": "continuationLineIndent",
"contents": {
"kind": "group",
"document": {
"kind": "recurse_field",
"field": "f_cond_expr"
}
}
},
"hardline",
{
"kind": "text",
"text": "then"
}
]
},
{
"kind": "indent",
"contents": [
"hardlineWithoutBreakParent",
{
"kind": "recurse_field",
"field": "f_stmts"
}
],
"bubbleUpTrailingTrivias": true
}
]
}
},
"IfStmt": {
"node": {
"kind": "group",
"document": [
{
"kind": "group",
"document": [
{
"kind": "continuationLineIndent",
"contents": {
"kind": "group",
"document": [
{
"kind": "text",
"text": "if"
},
"whitespace",
"flushLineBreaks",
{
"kind": "recurse_field",
"field": "f_cond_expr"
}
]
}
},
"hardline",
{
"kind": "text",
"text": "then"
}
]
},
{
"kind": "recurse_field",
"field": "f_then_stmts"
},
{
"kind": "recurse_field",
"field": "f_alternatives"
},
{
"kind": "recurse_field",
"field": "f_else_part"
},
"hardlineWithoutBreakParent",
{
"kind": "text",
"text": "end"
},
"whitespace",
{
"kind": "text",
"text": "if"
},
{
"kind": "text",
"text": ";"
}
]
},
"fields": {
"f_then_stmts": [
{
"kind": "indent",
"contents": [
"hardlineWithoutBreakParent",
"recurse"
],
"bubbleUpTrailingTrivias": true
}
],
"f_alternatives": {
"kind": "if",
"condition": {"kind": "is_empty", "node": "this_field"},
"then": "recurse",
"else": [
"hardlineWithoutBreakParent",
"recurse"
]
}
}
}
}
}
Note
This configuration snippet produces the same result as the gnatpp
--separate-then switch.
4.3.5. ForLoopStmt and WhileLoopStmt rewrite to split before loop
This configuration snippet illustrates ForLoopStmt and WhileLoopStmt node
rewriting to enforce a line break before the loop keyword. This will place
the keyword loop in FOR and WHILE loop statements on a separate line.
Input code
Consider the following code snippet:
procedure Separate_Loop is
begin
while Foo loop
null;
end loop;
for Foo of Bar when Foo.Is_Baz loop
null;
end loop;
end Separate_Loop;
Expected output code
The desired layout is structured as follows:
procedure Separate_Loop is
begin
while Foo
loop
null;
end loop;
for Foo of Bar when Foo.Is_Baz
loop
null;
end loop;
end Separate_Loop;
Configuration snippet
This result is obtained using the following custom configuration:
{
"node_configs": {
"ForLoopStmt": {
"node": {
"kind": "group",
"document": [
{
"kind": "group",
"document": [
{
"kind": "text",
"text": "for"
},
"whitespace",
{
"kind": "recurse_field",
"field": "f_spec"
},
"hardline",
{
"kind": "text",
"text": "loop"
}
]
},
{
"kind": "indent",
"contents": [
"hardline",
{
"kind": "recurse_field",
"field": "f_stmts"
}
]
},
"hardline",
{
"kind": "text",
"text": "end"
},
"whitespace",
{
"kind": "text",
"text": "loop"
},
{
"kind": "recurse_field",
"field": "f_end_name"
},
{
"kind": "text",
"text": ";"
}
]
},
"fields": {
"f_end_name": [
"whitespace",
"recurse"
]
}
},
"WhileLoopStmt": {
"node": {
"kind": "group",
"document": [
{
"kind": "group",
"document": [
{
"kind": "continuationLineIndent",
"contents": {
"kind": "recurse_field",
"field": "f_spec"
}
},
"hardline",
{
"kind": "text",
"text": "loop"
}
]
},
{
"kind": "indent",
"contents": [
"hardline",
{
"kind": "recurse_field",
"field": "f_stmts"
}
]
},
"hardline",
{
"kind": "text",
"text": "end"
},
"whitespace",
{
"kind": "text",
"text": "loop"
},
{
"kind": "recurse_field",
"field": "f_end_name"
},
{
"kind": "text",
"text": ";"
}
]
},
"fields": {
"f_end_name": [
"whitespace",
"recurse"
]
}
}
}
}
Note
This configuration snippet produces the same result as the gnatpp
--separate-loop switch.
4.3.6. Named Aggregate rewrite to enforce vertical formatting
This configuration snippets illustrates how the AggregateAssoc node
is rewritten to force vertical formatting when named notation is used for
any component association, placing each component association on its own
line. Hence, the AggregateAssoc node undergoes a rewrite whenever named
notation is applied to one or more component associations.
Input code
Consider the following code snippet:
procedure Main is
A : constant Foo := Bar'(A, B);
B : constant Foo := Bar'(A=>A, B=>B);
begin
F1 := (1, 2, B => 3);
F2 := (B1 => 1, B2 => 2, others => 0);
F3 := [B => Val_1, Q => 15];
end Main;
Expected output code
The desired layout is structured as follows:
procedure Main is
A : constant Foo := Bar'(A, B);
B : constant Foo :=
Bar'
(A => A,
B => B);
begin
F1 :=
(1,
2,
B => 3);
F2 :=
(B1 => 1,
B2 => 2,
others => 0);
F3 :=
[B => Val_1,
Q => 15];
end Main;
Configuration snippet
This result is obtained using the following custom configuration:
{
"node_configs": {
"AggregateAssoc": {
"node": [
{
"field": "f_designators",
"kind": "recurse_field"
},
{
"kind": "if",
"condition": {
"kind": "eval_member",
"prefix": {
"kind": "eval_member",
"prefix": "this_node",
"member": "f_designators"
},
"member": "is_empty_list"
},
"then": {
"kind": "group",
"document": [
{
"field": "f_r_expr",
"kind": "recurse_field"
}
]
},
"else": {
"kind": "group",
"document": {
"kind": "continuationLineIndent",
"contents": [
{
"kind": "match",
"node": {
"kind": "eval_member",
"member": "parent",
"prefix": "this_node"
},
"matchers": [
{
"pattern": {
"kind": "node",
"type": "AssocList",
"members": [
{
"member": "parent",
"pattern": {
"kind": "node",
"type": "Aggregate",
"members": [
{
"member": "parent",
"pattern": {
"kind": "node",
"type": "AspectAssoc",
"members": [
{
"member": "f_id",
"pattern": {
"kind": "node",
"type": "Identifier",
"members": [
{
"member": "p_canonical_text",
"pattern": {
"kind": "symbol_literal",
"value": "depends"
}
}
]
}
}
]
}
}
]
}
}
]
},
"document": []
},
{
"pattern": "*",
"document": [
"line"
]
}
]
},
"flushLineBreaks",
{
"field": "f_r_expr",
"kind": "recurse_field"
}
]
}
}
},
{
"kind": "match",
"node": "this_node",
"matchers": [
{
"pattern": {
"kind": "node",
"type": "AggregateAssoc",
"members": [
{
"member": "previous_sibling",
"pattern": null
},
{
"member": "next_sibling",
"pattern": null
}
]
},
"document": []
},
{
"pattern": {
"kind": "node",
"type": "AggregateAssoc",
"members": [
{
"member": "f_designators",
"pattern": {
"kind": "node",
"type": "AlternativesList",
"members": [
{
"member": "is_empty_list",
"pattern": false
}
]
}
},
{
"member": "parent",
"pattern": {
"kind": "node",
"type": "AssocList",
"members": [
{
"member": "parent",
"pattern": {
"kind": "node",
"type": "Aggregate"
}
}
]
}
}
]
},
"document": "breakParent"
},
{
"pattern": "*",
"document": []
}
]
}
],
"fields": {
"f_designators": [
{
"kind": "group",
"document": "recurse"
},
{
"kind": "tableSeparator",
"text": ""
},
{
"kind": "group",
"document": {
"kind": "continuationLineIndent",
"contents": {
"kind": "dedent",
"contents": {
"kind": "group",
"document": [
"line",
{
"kind": "text",
"text": "=>"
}
]
},
"bubbleUpLeadingTrivias": true,
"bubbleUpTrailingTrivias": true
}
}
}
]
}
}
}
}
4.3.7. ObjectDecl rewrite to enforce alignment on separators
This configuration snippet illustrates ObjectDecl node rewriting to enforce
alignment for : and := separators across object declarations.
Inserting a blank line acts as a boundary that breaks the alignment.
Input code
Consider the following code:
package ObjDecl_Align is
Var_Int : constant Integer := 15;
Var_Bool : Boolean := True;
Var_Float : Float := 0.1;
Var_After_Blank_Line_Sep : Integer := 123;
end ObjDecl_Align;
Expected output code
The desired layout is structured as follows:
package ObjDecl_Align is
Var_Int : constant Integer := 15;
Var_Bool : Boolean := True;
Var_Float : Float := 0.1;
Var_After_Blank_Line_Sep : Integer := 123;
end ObjDecl_Align;
Configuration snippet
This result is produced using the following custom configuration:
{
"node_configs": {
"ObjectDecl": {
"node": [
{
"kind": "group",
"document": [
{
"kind": "recurse_field",
"field": "f_ids"
},
"whitespace"
]
},
{
"kind": "tableSeparator",
"text": ":"
},
{
"kind": "group",
"document": [
{
"kind": "group",
"document": [
{
"kind": "continuationLineIndent",
"contents": [
"line",
{
"kind": "group",
"document": [
{"kind": "recurse_field", "field": "f_has_aliased"},
{
"kind": "if",
"condition": {
"kind": "is_a",
"node": {
"kind": "eval_member",
"member": "f_has_aliased",
"prefix": "this_node"
},
"pattern": {
"kind": "node",
"type": "AliasedPresent"
}
},
"then": "whitespace",
"else": []
},
{"kind": "recurse_field", "field": "f_has_constant"},
{
"kind": "if",
"condition": {
"kind": "is_a",
"node": {
"kind": "eval_member",
"member": "f_has_constant",
"prefix": "this_node"
},
"pattern": {
"kind": "node",
"type": "ConstantPresent"
}
},
"then": "whitespace",
"else": []
},
{
"kind": "recurse_field",
"field": "f_mode"
},
{
"kind": "recurse_field",
"field": "f_type_expr"
}
]
}
]
}
]
}
],
"id": "object_decl_type"
},
{
"kind": "recurse_field",
"field": "f_default_expr"
},
{
"kind": "recurse_field",
"field": "f_renaming_clause"
},
{
"kind": "recurse_field",
"field": "f_aspects"
},
{
"kind": "text",
"text": ";"
}
],
"fields": {
"f_renaming_clause": [
"whitespace",
{
"kind": "ifBreak",
"breakContents": {
"kind": "continuationLineIndent",
"contents": {
"kind": "continuationLineIndent",
"contents": "recurse"
}
},
"flatContents": {
"kind": "continuationLineIndent",
"contents": "recurse"
},
"groupId": "object_decl_type"
}
],
"f_default_expr": [
"whitespace",
{
"kind": "tableSeparator",
"text": ":="
},
{
"kind": "ifBreak",
"breakContents": {
"kind": "continuationLineIndent",
"contents": {
"kind": "continuationLineIndent",
"contents": {
"kind": "group",
"document": [
"line",
"recurse"
]
}
}
},
"flatContents": {
"kind": "continuationLineIndent",
"contents": {
"kind": "group",
"document": [
"line",
"recurse"
]
}
},
"groupId": "object_decl_type"
}
],
"f_aspects": [
"line",
"recurse"
]
}
}
}
}
4.3.8. RecordDef rewrite to break before record
This configuration snippet illustrates RecordDef node rewriting to enforce
line split before the record keyword in a record type declaration, e.g. the
record keyword goes on a separate line.
Input code
Consider the following code:
type Date is record
Day : Integer range 1 .. 31;
Month : Month_Enum;
Year : Integer range 0 .. 4000;
end record;
Expected output code
The desired layout is structured as follows:
type Date is
record
Day : Integer range 1 .. 31;
Month : Month_Enum;
Year : Integer range 0 .. 4000;
end record;
Configuration snippet
This result is produced using the following custom configuration:
{
"node_configs": {
"RecordDef": {
"node": {
"kind": "group",
"document": [
{
"kind": "indent",
"contents": [
"hardline",
{
"kind": "text",
"text": "record"
},
{
"kind": "indent",
"contents": {
"kind": "recurse_field",
"field": "f_components"
}
},
"hardline",
{
"kind": "text",
"text": "end"
},
"whitespace",
{
"kind": "text",
"text": "record"
}
]
}
]
}
}
}
}
Note
This configuration snippet produces the same result as the gnatpp
--split-line-before-record switch.