zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

uses.ex (2331B)


      1 defmodule Absinthe.Phase.Document.Uses do
      2   @moduledoc false
      3 
      4   # Tracks uses of:
      5   # - Variables
      6   # - Fragments
      7 
      8   use Absinthe.Phase
      9   alias Absinthe.Blueprint
     10 
     11   @typep acc_t :: %{
     12            fragments_available: [Blueprint.Document.Fragment.Named.t()],
     13            fragments: [Blueprint.Document.Fragment.Named.Use.t()],
     14            variables: [Blueprint.Input.Variable.Use.t()]
     15          }
     16 
     17   @spec run(Blueprint.t(), Keyword.t()) :: {:ok, Blueprint.t()}
     18   def run(input, _options \\ []) do
     19     ops = Enum.map(input.operations, &add_uses(&1, input))
     20     node = %{input | operations: ops}
     21     {:ok, node}
     22   end
     23 
     24   @spec add_uses(Blueprint.Document.Operation.t(), Blueprint.t()) ::
     25           Blueprint.Document.Operation.t()
     26   defp add_uses(%Blueprint.Document.Operation{} = node, doc) do
     27     acc = %{
     28       fragments_available: doc.fragments,
     29       fragments: [],
     30       variables: []
     31     }
     32 
     33     {_, acc} = Blueprint.prewalk(node, acc, &handle_use/2)
     34 
     35     %{
     36       node
     37       | fragment_uses: acc.fragments ++ node.fragment_uses,
     38         variable_uses: acc.variables ++ node.variable_uses
     39     }
     40   end
     41 
     42   @spec handle_use(Blueprint.node_t(), acc_t) :: {Blueprint.node_t(), acc_t}
     43   defp handle_use(%Blueprint.Document.Fragment.Spread{} = node, acc) do
     44     if uses?(acc.fragments, node) do
     45       {node, acc}
     46     else
     47       target_fragment = Enum.find(acc.fragments_available, &(&1.name == node.name))
     48 
     49       if target_fragment do
     50         acc = acc |> put_use(target_fragment)
     51         {_, acc} = Blueprint.prewalk(target_fragment, acc, &handle_use/2)
     52         {node, acc}
     53       else
     54         {node, acc}
     55       end
     56     end
     57   end
     58 
     59   defp handle_use(%Blueprint.Input.Variable{} = node, acc) do
     60     {node, put_use(acc, node)}
     61   end
     62 
     63   defp handle_use(node, acc) do
     64     {node, acc}
     65   end
     66 
     67   @spec uses?([Blueprint.use_t()], Blueprint.Document.Fragment.Spread.t()) :: boolean
     68   defp uses?(list, node) do
     69     Enum.find(list, &(&1.name == node.name))
     70   end
     71 
     72   @spec put_use(acc_t, Blueprint.node_t()) :: acc_t
     73   defp put_use(acc, %Blueprint.Input.Variable{} = node) do
     74     ref = Blueprint.Input.Variable.to_use(node)
     75     update_in(acc.variables, &[ref | &1])
     76   end
     77 
     78   defp put_use(acc, %Blueprint.Document.Fragment.Named{} = node) do
     79     ref = Blueprint.Document.Fragment.Named.to_use(node)
     80     update_in(acc.fragments, &[ref | &1])
     81   end
     82 end