@@ -92,6 +92,41 @@ defmodule Igniter.Libs.Phoenix do
9292 Module . concat ( web_module ( igniter ) , suffix )
9393 end
9494
95+ @ doc """
96+ Returns the web module that the given `router` belongs to.
97+
98+ Reads the router's `use <WebModule>, :router` declaration, which is the module
99+ that generated modules (`use <WebModule>, :controller`, `:verified_routes`,
100+ etc.) should reference. This lets installers place generated modules alongside
101+ the selected router rather than assuming the application's default web module.
102+
103+ Falls back to `web_module/1` when the router uses `Phoenix.Router` directly or
104+ cannot be found.
105+ """
106+ @ spec web_module_for_router ( Igniter . t ( ) , module ( ) ) :: { Igniter . t ( ) , module ( ) }
107+ def web_module_for_router ( igniter , router ) do
108+ case Igniter.Project.Module . find_module ( igniter , router ) do
109+ { :ok , { igniter , _source , zipper } } ->
110+ { igniter , web_module_from_router_use ( zipper ) || web_module ( igniter ) }
111+
112+ { :error , igniter } ->
113+ { igniter , web_module ( igniter ) }
114+ end
115+ end
116+
117+ defp web_module_from_router_use ( zipper ) do
118+ with { :ok , use_call } <-
119+ Igniter.Code.Function . move_to_function_call ( zipper , :use , 2 , fn call ->
120+ Igniter.Code.Function . argument_equals? ( call , 1 , :router )
121+ end ) ,
122+ { :ok , arg } <- Igniter.Code.Function . move_to_nth_argument ( use_call , 0 ) ,
123+ { :__aliases__ , _ , parts } <- Igniter.Code.Common . expand_aliases ( arg ) . node do
124+ Module . concat ( parts )
125+ else
126+ _ -> nil
127+ end
128+ end
129+
95130 @ doc "Gets the list of endpoints that use a given router"
96131 @ spec endpoints_for_router ( igniter :: Igniter . t ( ) , router :: module ( ) ) ::
97132 { Igniter . t ( ) , list ( module ( ) ) }
0 commit comments