rejuvenation_22.0.1_a6990d10/src/rejuvenation-utils.adb

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
with Ada.Strings;           use Ada.Strings;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Strings.Equal_Case_Insensitive;
with Langkit_Support.Text;  use Langkit_Support.Text;

package body Rejuvenation.Utils is

   -- Raw signature --------

   function Raw_Signature
     (Node : Ada_Node'Class; Before, After : Node_Location := No_Trivia)
      return String
   is
   begin
      if Node.Is_Null then
         return "";
      else
         declare
            First    : constant Positive      := Start_Offset (Node, Before);
            Last     : constant Natural       := End_Offset (Node, After);
            Unit     : constant Analysis_Unit := Node.Unit;
            Node_Str : constant String        :=
              Encode (Unit.Text (First .. Last), Unit.Get_Charset);
         begin
            return Node_Str;
         end;
      end if;
   end Raw_Signature;

   function Raw_Signature
     (Token : Token_Reference; Charset : String) return String is
     (if Token = No_Token then "" else Encode (Text (Token), Charset));

   function Raw_Signature
     (First_Node, Last_Node : Ada_Node'Class;
      Before, After         : Node_Location := No_Trivia) return String
   is
      First : constant Positive      := Start_Offset (First_Node, Before);
      Last  : constant Natural       := End_Offset (Last_Node, After);
      Unit  : constant Analysis_Unit := First_Node.Unit;
      Str   : constant String        :=
        Encode (Unit.Text (First .. Last), Unit.Get_Charset);
   begin
      return Str;
   end Raw_Signature;

   function Are_Equal_As_Raw_Signature
     (Node1, Node2 : Ada_Node'Class) return Boolean
   is
   begin
      return Raw_Signature (Node1) = Raw_Signature (Node2);
   end Are_Equal_As_Raw_Signature;

   function Are_Equal_Case_Insensitive_As_Raw_Signature
     (Node1, Node2 : Ada_Node'Class) return Boolean
   is
   begin
      return
        Equal_Case_Insensitive (Raw_Signature (Node1), Raw_Signature (Node2));
   end Are_Equal_Case_Insensitive_As_Raw_Signature;

   --  Package (Distributed over files) functionality

   function In_Same_Package (Unit1, Unit2 : Analysis_Unit) return Boolean is
      Unit1_Filename : constant String := Unit1.Get_Filename;
      Unit2_Filename : constant String := Unit2.Get_Filename;
   begin
      --  TODO: should the comparison be case insensitive?
      --  TODO: This works for packages X defined in X.ads and X.adb
      --        but does it also work for separates?
      return
        Unit1_Filename (Unit1_Filename'First .. Unit1_Filename'Last - 1) =
        Unit2_Filename (Unit2_Filename'First .. Unit2_Filename'Last - 1);
   end In_Same_Package;

   -- Image --------

   function Image (Node_List_Vector : Node_List.Vector) return String is
   begin
      if Node_List_Vector.Length = 0 then
         return "[]";
      else
         declare
            Str : Unbounded_String :=
              To_Unbounded_String (Node_List_Vector.First_Element.Image);
         begin
            for Index in
              Node_List_Vector.First_Index + 1 .. Node_List_Vector.Last_Index
            loop
               Str :=
                 Str & ", " &
                 Node_List_Vector.Element (Positive (Index)).Image;
            end loop;
            return "[" & To_String (Str) & "]";
         end;
      end if;
   end Image;

   -- Get trivia tokens --------

   function Get_Trivia_Before (Node : Ada_Node'Class) return Token_List.Vector
   is
   begin
      return Get_Trivia_Before (Node.Token_Start);
   end Get_Trivia_Before;

   function Get_Trivia_Before
     (Token : Token_Reference) return Token_List.Vector
   is
      Results       : Token_List.Vector;
      Running_Token : Token_Reference := Previous (Token);
   begin
      while Is_Trivia (Running_Token) loop
         Token_List.Prepend (Results, Running_Token);
         Running_Token := Previous (Running_Token);
      end loop;
      return Results;
   end Get_Trivia_Before;

   function Get_Trivia_After (Node : Ada_Node'Class) return Token_List.Vector
   is
   begin
      return Get_Trivia_After (Node.Token_End);
   end Get_Trivia_After;

   function Get_Trivia_After (Token : Token_Reference) return Token_List.Vector
   is
      Results       : Token_List.Vector;
      Running_Token : Token_Reference := Next (Token);
   begin
      while Is_Trivia (Running_Token) loop
         Token_List.Append (Results, Running_Token);
         Running_Token := Next (Running_Token);
      end loop;
      return Results;
   end Get_Trivia_After;

   function Get_Tokens (Node : Ada_Node'Class) return Token_List.Vector is
      Results       : Token_List.Vector;
      Running_Token : Token_Reference := Node.Token_Start;
   begin
      while Running_Token /= Node.Token_End loop
         Token_List.Append (Results, Running_Token);
         Running_Token := Next (Running_Token);
      end loop;
      Token_List.Append (Results, Running_Token);
      return Results;
   end Get_Tokens;

end Rejuvenation.Utils;