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.