
with Ada.Text_IO;

with Asis.Report;
with Asis.Expressions;
with Asis.Elements;

with Asis.Toolkit.ObjectAda.Declarations;
with Ada.Characters.Handling;

package body Asis.Toolkit.ObjectAda.Expressions is

  package TOOLDECL renames Asis.Toolkit.ObjectAda.Declarations;

  Debug : constant Boolean := 
	      Asis.Report.Debug ( "Asis.Toolkit.ObjectAda.Expressions.Debug" );

  function Entity_Name_Image
		  (Expr : in Asis.Expression) return String is
  begin
    case Asis.Elements.Expression_Kind(Expr) is

      when Asis.An_Indexed_Component |
           Asis.A_Function_Call |
           Asis.A_Slice |
           Asis.An_Explicit_Dereference |
           Asis.An_Attribute_Reference =>
        return Entity_Name_Image(Asis.Expressions.Prefix(Expr));

      when Asis.A_Parenthesized_Expression =>
        return Entity_Name_Image
		   (Asis.Expressions.Expression_Parenthesized(Expr));

      when Asis.A_Selected_Component =>
        return Entity_Name_Image(Asis.Expressions.Prefix(Expr)) & "." &
               Entity_Name_Image(Asis.Expressions.Selector(Expr));

      when Asis.An_Identifier |
           Asis.An_Operator_Symbol |
           Asis.A_Character_Literal |
           Asis.An_Enumeration_Literal =>
        return Ada.Characters.Handling.To_String
	             (Asis.Expressions.Name_Image(Expr));

      when others => null;
        if Debug then
          Ada.Text_IO.Put(Item => "Entity_Name_Image:Ignored ");
          Ada.Text_IO.Put_Line(Item => Asis.Expression_Kinds'Image
			               (Asis.Elements.Expression_Kind(Expr)));
        end if;
    end case;
    return "";
  end Entity_Name_Image;


  function First_Prefix
		  (Expr : in Asis.Expression) return Asis.Expression is
  begin
    case Asis.Elements.Expression_Kind(Expr) is

      when Asis.An_Indexed_Component |
           Asis.A_Function_Call |
           Asis.A_Slice |
           Asis.An_Explicit_Dereference |
           Asis.An_Attribute_Reference =>
        return First_Prefix(Asis.Expressions.Prefix(Expr));

      when Asis.A_Parenthesized_Expression =>
        return First_Prefix
		   (Asis.Expressions.Expression_Parenthesized(Expr));

      when Asis.A_Selected_Component =>
	-- for A.B.C we want A so keep working on the prefix A.B
        return First_Prefix(Asis.Expressions.Prefix(Expr));

      when Asis.An_Identifier |
           Asis.An_Operator_Symbol |
           Asis.A_Character_Literal |
           Asis.An_Enumeration_Literal =>

        return Expr;

      when others => null;
    end case;
    return Asis.Nil_Element;
  end First_Prefix;


  function Entity_Full_Expanded_Name_Image
		  (Expr : in Asis.Expression) return String is
  begin
    if Debug then
      Ada.Text_IO.Put_Line(Item => "EFENI:" & Asis.Expression_Kinds'Image
			               (Asis.Elements.Expression_Kind(Expr)));
    end if;

    case Asis.Elements.Expression_Kind(Expr) is

      when Asis.An_Indexed_Component |
           Asis.A_Function_Call |
           Asis.A_Slice |
           Asis.An_Explicit_Dereference |
           Asis.An_Attribute_Reference =>
        return Entity_Full_Expanded_Name_Image(Asis.Expressions.Prefix(Expr));

      when Asis.A_Parenthesized_Expression =>
        return Entity_Full_Expanded_Name_Image
		   (Asis.Expressions.Expression_Parenthesized(Expr));

      when Asis.A_Selected_Component =>
	--# strip leading dot
        return TOOLDECL.Parent_Full_Expanded_Name_Image
		  (Entity_Declaration(First_Prefix(Expr))) & "." &
               Entity_Name_Image(Expr);

      when Asis.An_Identifier |
           Asis.An_Operator_Symbol |
           Asis.A_Character_Literal |
           Asis.An_Enumeration_Literal =>

	--# strip leading dot
        return TOOLDECL.Parent_Full_Expanded_Name_Image
		  (Entity_Declaration(Expr)) & "." &
	       Entity_Name_Image(Expr);

      when others => null;
	if Debug then
          Ada.Text_IO.Put(Item => "Entity_Full_Expanded_Name_Image:Ignored ");
	end if;
    end case;
    return "";
  end Entity_Full_Expanded_Name_Image;


  function Entity_Declaration
		  (Expr : in Asis.Expression) return Asis.Declaration is
  begin
    case Asis.Elements.Expression_Kind(Expr) is

      when Asis.An_Indexed_Component |
           Asis.A_Function_Call |
           Asis.A_Slice |
           Asis.An_Explicit_Dereference |
           Asis.An_Attribute_Reference =>
        return Entity_Declaration(Asis.Expressions.Prefix(Expr));

      when Asis.A_Parenthesized_Expression =>
        return Entity_Declaration
		   (Asis.Expressions.Expression_Parenthesized(Expr));

      when Asis.A_Selected_Component =>
        return Entity_Declaration(Asis.Expressions.Selector(Expr));

      when Asis.An_Identifier |
           Asis.An_Operator_Symbol |
           Asis.A_Character_Literal |
           Asis.An_Enumeration_Literal =>
	return Asis.Expressions.Corresponding_Name_Declaration(Expr);

      when others => null;
	if Debug then
          Ada.Text_IO.Put(Item => "Entity_Declaration:Ignored ");
          Ada.Text_IO.Put_Line(Item => Asis.Expression_Kinds'Image
 			               (Asis.Elements.Expression_Kind(Expr)));
	end if;
    end case;
    return Asis.Nil_Element;
  end Entity_Declaration;

end Asis.Toolkit.ObjectAda.Expressions;
