-- -- Copyright (C) 2024, AdaCore -- SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -- with Ada.Strings.Unbounded; with Gnatformat.Utils; with GNATCOLL.VFS; with GPR2.Project.View; with GPR2.Project.Attribute; with Langkit_Support.Generic_API.Unparsing; with Prettier_Ada.Documents; private with Ada.Containers.Hashed_Maps; private with Ada.Containers.Indefinite_Hashed_Maps; private with Ada.Strings.Hash; private with GPR2.View_Ids; private with Libadalang.Generic_API; with Langkit_Support.Diagnostics; package Gnatformat.Configuration is Default_Charset : constant String := "iso-8859-1"; type Format_Options_Type; procedure Elaborate_GPR2; -- Updates the GPR2 registry with the following: -- -- - package Format -- - atribute Width, Indentation, Indentation_Kind and End_Of_Line -- indexed by language or source. type Indentation_Kind is (Spaces, Tabs); type End_Of_Line_Kind is (LF, CRLF); package Optional_Indentation_Kinds is new Gnatformat.Utils.Optional (Indentation_Kind); subtype Optional_Indentation_Kind is Optional_Indentation_Kinds.Optional_Type; package Optional_End_Of_Line_Kinds is new Gnatformat.Utils.Optional (End_Of_Line_Kind); subtype Optional_End_Of_Line_Kind is Optional_End_Of_Line_Kinds.Optional_Type; package Optional_Positives is new Gnatformat.Utils.Optional (Positive); subtype Optional_Positive is Optional_Positives.Optional_Type; package Optional_Unbounded_Strings is new Gnatformat.Utils.Optional (Ada.Strings.Unbounded.Unbounded_String); subtype Optional_Unbounded_String is Optional_Unbounded_Strings.Optional_Type; type Format_Options_Type is private; function Get_Charset (Self : Format_Options_Type; Source_Filename : String; Language_Fallback : Supported_Languages := Ada_Language) return Ada.Strings.Unbounded.Unbounded_String; -- Retrieves the charset option for the specified Source_Filename if it -- exists. -- If the charset option for Source_Filename does not exist, the function -- will fall back to the charset option associated with the given -- Language_Fallback if it is available. -- If neither the Source_Filename charset option nor the Language_Fallback -- option is available, the function returns the default charset defined -- by Default_Basic_Format_Options.Charset.Value. function Get_End_Of_Line (Self : Format_Options_Type; Source_Filename : String; Language_Fallback : Supported_Languages := Ada_Language) return End_Of_Line_Kind; -- Retrieves the end-of-line option for the specified Source_Filename if it -- exists. -- If the end-of-line option for Source_Filename does not exist, the -- function will fall back to the end-of-line option associated with the -- given Language_Fallback if it is available. -- If neither the Source_Filename end-of-line option nor the -- Language_Fallback option is available, the function returns the default -- end-of-line value defined by -- Default_Basic_Format_Options.End_Of_Line.Value. function Get_Indentation (Self : Format_Options_Type; Source_Filename : String; Language_Fallback : Supported_Languages := Ada_Language) return Positive; -- Retrieves the indentation option for the specified Source_Filename if it -- exists. -- If the indentation option for Source_Filename does not exist, the -- function will fall back to the indentation option associated with the -- given Language_Fallback if it is available. -- If neither the Source_Filename indentation option nor the -- Language_Fallback option is available, the function returns the default -- indentation value defined by -- Default_Basic_Format_Options.End_Of_Line.Value. function Get_Indentation_Kind (Self : Format_Options_Type; Source_Filename : String; Language_Fallback : Supported_Languages := Ada_Language) return Indentation_Kind; -- Retrieves the indentaiton-kind option for the specified Source_Filename -- if it exists. -- If the indentaiton-kind option for Source_Filename does not exist, the -- function will fall back to the indentaiton-kind option associated with -- the given Language_Fallback if it is available. -- If neither the Source_Filename indentaiton-kind option nor the -- Language_Fallback option is available, the function returns the default -- indentaiton-kind value defined by -- Default_Basic_Format_Options.End_Of_Line.Value. function Get_Indentation_Continuation (Self : Format_Options_Type; Source_Filename : String; Language_Fallback : Supported_Languages := Ada_Language) return Positive; -- Retrieves the indentaiton-continuation option for the specified -- Source_Filename it exists. -- If the indentaiton-continuation option for Source_Filename does not -- exist, the function will fall back to the indentaiton-continuation -- option associated with the given Language_Fallback if it is available. -- If neither the Source_Filename indentaiton-continuation option nor the -- Language_Fallback option is available, the function returns the default -- indentaiton-continuation value defined by -- Default_Basic_Format_Options.End_Of_Line.Value. function Get_Width (Self : Format_Options_Type; Source_Filename : String; Language_Fallback : Supported_Languages := Ada_Language) return Positive; -- Retrieves the width option for the specified Source_Filename if it -- exists. -- If the width option for Source_Filename does not exist, the -- function will fall back to the width option associated with the -- given Language_Fallback if it is available. -- If neither the Source_Filename width option nor the -- Language_Fallback option is available, the function returns the default -- width value defined by -- Default_Basic_Format_Options.End_Of_Line.Value. function From_Project (Project : GPR2.Project.View.Object) return Format_Options_Type; -- Creates a Format_Options_Type by parsing Project's Format package function Into (Self : Format_Options_Type; Language : Supported_Languages) return Prettier_Ada.Documents.Format_Options_Type; -- Converts a Format_Options_type for the provided Language into an -- equivalent Prettier_Ada Format_Options.Type. If there's no configuration -- associated to Language, then returns Default_Format_Options. function Into (Self : Format_Options_Type; Source_Filename : String) return Prettier_Ada.Documents.Format_Options_Type; -- Converts a Format_Options_type for the provided Source_Filename into an -- equivalent Prettier_Ada Format_Options.Type. If there's no configuration -- associated to Source_Filename, then returns Default_Format_Options. function Into (Self : Format_Options_Type; Source_Filename : String; Language_Fallback : Supported_Languages) return Prettier_Ada.Documents.Format_Options_Type; -- Converts a Format_Options_type for the provided Source_Filename into an -- equivalent Prettier_Ada Format_Options.Type. If there's no configuration -- for this source, then fallback to the configuration associated to -- Langauge_Fallback. If there's no configuration for Language_Fallback -- returns Default_Format_Options. procedure Overwrite (Target : in out Format_Options_Type; Source : Format_Options_Type); -- Overwrites Target's options by Source's ones Default_Format_Options : constant Format_Options_Type; type Project_Format_Options_Cache_Type is private; function Create_Project_Format_Options_Cache return Project_Format_Options_Cache_Type; -- Project_Format_Options_Cache_Type constructor. -- -- Use this cache if you need to repeatedly retrive format options for the -- same project view. function Get (Self : in out Project_Format_Options_Cache_Type; Project : GPR2.Project.View.Object) return Format_Options_Type; -- Retrives the format options associated to Project using a cached result -- if existent. Otherwise the format options are computed. type Format_Options_Builder_Type is private; function Create_Format_Options_Builder return Format_Options_Builder_Type; -- Format_Options_Builder_Type constructor. -- -- A builder of Format_Options_Type. function Build (Self : Format_Options_Builder_Type) return Format_Options_Type; -- Returns the format options current state procedure With_Charset (Self : in out Format_Options_Builder_Type; Charset : Ada.Strings.Unbounded.Unbounded_String; Language : Supported_Languages); -- Sets the format option Charset for the provided Language procedure With_Charset (Self : in out Format_Options_Builder_Type; Charset : Ada.Strings.Unbounded.Unbounded_String; Source_Filename : String); -- Sets the format option Charset for the provided Source_Filename procedure With_End_Of_Line (Self : in out Format_Options_Builder_Type; End_Of_Line : End_Of_Line_Kind; Language : Supported_Languages); -- Sets the format option End_Of_Line for the provided Language procedure With_End_Of_Line (Self : in out Format_Options_Builder_Type; End_Of_Line : End_Of_Line_Kind; Source_Filename : String); -- Sets the format option End_Of_Line for the provided Source_Filename procedure With_From_Attribute (Self : in out Format_Options_Builder_Type; Attribute : GPR2.Project.Attribute.Object); -- Parses Attribute and sets a format option according to the Attribute id -- and value. If the Attribute id is unknown, then it's ignored. procedure With_Indentation (Self : in out Format_Options_Builder_Type; Indentation : Positive; Language : Supported_Languages); -- Sets the format option Indentation for the provided Language procedure With_Indentation (Self : in out Format_Options_Builder_Type; Indentation : Positive; Source_Filename : String); -- Sets the format option Indentation for the provided Source_Filename procedure With_Indentation_Continuation (Self : in out Format_Options_Builder_Type; Indentation_Continuation : Positive; Language : Supported_Languages); -- Sets the format option Indentation_Continuation for the provided -- Language. procedure With_Indentation_Continuation (Self : in out Format_Options_Builder_Type; Indentation_Continuation : Positive; Source_Filename : String); -- Sets the format option Indentation_Continuation for the provided -- Source_Filename. procedure With_Indentation_Kind (Self : in out Format_Options_Builder_Type; Indentation_Kind : Gnatformat.Configuration.Indentation_Kind; Language : Supported_Languages); -- Sets the format option Indentation_Kind for the provided Language procedure With_Indentation_Kind (Self : in out Format_Options_Builder_Type; Indentation_Kind : Gnatformat.Configuration.Indentation_Kind; Source_Filename : String); -- Sets the format option Indentation_Kind for the provided Source_Filename procedure With_Width (Self : in out Format_Options_Builder_Type; Width : Positive; Language : Supported_Languages); -- Sets the format option Width for the provided Language procedure With_Width (Self : in out Format_Options_Builder_Type; Width : Positive; Source_Filename : String); -- Sets the format option Width for the provided Source_Filename Default_Unparsing_Configuration : constant Langkit_Support.Generic_API.Unparsing.Unparsing_Configuration; function Load_Unparsing_Configuration (Unparsing_Configuration_File : GNATCOLL.VFS.Virtual_File; Diagnostics : in out Langkit_Support.Diagnostics.Diagnostics_Vectors.Vector) return Langkit_Support.Generic_API.Unparsing.Unparsing_Configuration; -- Loads the formatting rules private Package_Id : constant GPR2.Package_Id := GPR2."+" ("format"); Width_Attribute_Id : constant GPR2.Attribute_Id := GPR2."+" ("width"); Q_Width_Attribute_Id : constant GPR2.Q_Attribute_Id := (Package_Id, Width_Attribute_Id); Indentation_Attribute_Id : constant GPR2.Attribute_Id := GPR2."+" ("indentation"); Q_Indentation_Attribute_Id : constant GPR2.Q_Attribute_Id := (Package_Id, Indentation_Attribute_Id); Indentation_Kind_Attribute_Id : constant GPR2.Attribute_Id := GPR2."+" ("indentation_kind"); Q_Indentation_Kind_Attribute_Id : constant GPR2.Q_Attribute_Id := (Package_Id, Indentation_Kind_Attribute_Id); Indentation_Continuation_Attribute_Id : constant GPR2.Attribute_Id := GPR2."+" ("indentation_continuation"); Q_Indentation_Continuation_Attribute_Id : constant GPR2.Q_Attribute_Id := (Package_Id, Indentation_Continuation_Attribute_Id); End_Of_Line_Attribute_Id : constant GPR2.Attribute_Id := GPR2."+" ("end_of_line"); Q_End_Of_Line_Attribute_Id : constant GPR2.Q_Attribute_Id := (Package_Id, End_Of_Line_Attribute_Id); Charset_Attribute_Id : constant GPR2.Attribute_Id := GPR2."+" ("charset"); Q_Charset_Attribute_Id : constant GPR2.Q_Attribute_Id := (Package_Id, Charset_Attribute_Id); type Basic_Format_Options_Type is record Width : Optional_Positive := (Is_Set => False); Indentation : Optional_Positive := (Is_Set => False); Indentation_Kind : Optional_Indentation_Kind := (Is_Set => False); Indentation_Continuation : Optional_Positive := (Is_Set => False); End_Of_Line : Optional_End_Of_Line_Kind := (Is_Set => False); Charset : Optional_Unbounded_String := (Is_Set => False); end record; function Into (Self : Basic_Format_Options_Type) return Prettier_Ada.Documents.Format_Options_Type; -- Converts a Basic_Format_Options_Type into an equivalent -- Prettier_Ada Format_Options.Type. function Into (Format_Options : Format_Options_Type; Source_Filename : String; Language_Fallback : Supported_Languages) return Basic_Format_Options_Type; -- Gets Basic_Format_Options_Type for Source_Filename if existent, -- otherwise fallsback Language_Fallback's Basic_Format_Options_Type. procedure Overwrite (Target : in out Basic_Format_Options_Type; Source : Basic_Format_Options_Type); -- Overwrites Target's options by Source's ones Default_Basic_Format_Options : constant Basic_Format_Options_Type := (Width => (Is_Set => True, Value => 79), Indentation => (Is_Set => True, Value => 3), Indentation_Kind => (Is_Set => True, Value => Spaces), Indentation_Continuation => (Is_Set => True, Value => 2), End_Of_Line => (Is_Set => True, Value => LF), Charset => (Is_Set => True, Value => Ada.Strings.Unbounded.To_Unbounded_String (Default_Charset))); Undefined_Basic_Format_Options : constant Basic_Format_Options_Type := (others => <>); package String_To_Basic_Format_Options_Hash_Maps is new Ada.Containers.Indefinite_Hashed_Maps (Key_Type => String, Element_Type => Basic_Format_Options_Type, Hash => Ada.Strings.Hash, Equivalent_Keys => "="); subtype String_To_Basic_Format_Options_Hash_Map is String_To_Basic_Format_Options_Hash_Maps.Map; type Supported_Languages_Format_Options_Type is array (Supported_Languages) of Basic_Format_Options_Type; type Format_Options_Type is record Language : Supported_Languages_Format_Options_Type := [others => Undefined_Basic_Format_Options]; Sources : String_To_Basic_Format_Options_Hash_Map := String_To_Basic_Format_Options_Hash_Maps.Empty_Map; end record; Default_Format_Options : constant Format_Options_Type := (Language => [others => Default_Basic_Format_Options], Sources => String_To_Basic_Format_Options_Hash_Maps.Empty_Map); package View_Ids_To_Format_Options_Hashed_Maps is new Ada.Containers.Hashed_Maps (Key_Type => GPR2.View_Ids.View_Id, Element_Type => Gnatformat.Configuration.Format_Options_Type, Hash => GPR2.View_Ids.Hash, Equivalent_Keys => GPR2.View_Ids."="); subtype View_Id_To_Format_Options_Hashed_Map is View_Ids_To_Format_Options_Hashed_Maps.Map; type Project_Format_Options_Cache_Type is tagged record Cache : View_Id_To_Format_Options_Hashed_Map; end record; type Format_Options_Builder_Type is tagged record Format_Options : Format_Options_Type; end record; Default_Unparsing_Configuration : constant Langkit_Support.Generic_API.Unparsing.Unparsing_Configuration := Langkit_Support.Generic_API.Unparsing.Default_Unparsing_Configuration (Language => Libadalang.Generic_API.Ada_Lang_Id); end Gnatformat.Configuration;