Class: ActionView::RenderParser
Do not use. This class is for internal use only.
| Relationships & Source Files | |
| Inherits: | Object |
| Defined in: | actionview/lib/action_view/render_parser.rb |
Constant Summary
-
ALL_KNOWN_KEYS =
# File 'actionview/lib/action_view/render_parser.rb', line 7[:partial, :template, :layout, :formats, :locals, :object, :collection, :as, :status, :content_type, :location, :spacer_template]
-
RENDER_TYPE_KEYS =
# File 'actionview/lib/action_view/render_parser.rb', line 8[:partial, :template, :layout]
Class Method Summary
- .new(name, code) ⇒ RenderParser constructor
Instance Method Summary
- #render_calls
- #directory private
- #partial_to_virtual_path(render_type, partial_path) private
-
#render_call_options(node)
private
Accept a call node and return a hash of options for the render call.
-
#render_call_template(node)
private
Accept the node that is being passed in the position of the template and return the template name and whether or not it is an object template.
Constructor Details
.new(name, code) ⇒ RenderParser
# File 'actionview/lib/action_view/render_parser.rb', line 10
def initialize(name, code) @name = name @code = code end
Instance Method Details
#directory (private)
[ GitHub ]# File 'actionview/lib/action_view/render_parser.rb', line 50
def directory File.dirname(@name) end
#partial_to_virtual_path(render_type, partial_path) (private)
[ GitHub ]# File 'actionview/lib/action_view/render_parser.rb', line 54
def partial_to_virtual_path(render_type, partial_path) if render_type == :partial || render_type == :layout partial_path.gsub(%r{(/|^)([^/]*)\z}, '\1_\2') else partial_path end end
#render_call_options(node) (private)
Accept a call node and return a hash of options for the render call. If it doesn’t match the expected format, return nil.
# File 'actionview/lib/action_view/render_parser.rb', line 64
def (node) # We are only looking for calls to render or render_to_string. name = node.name.to_sym return if name != :render && name != :render_to_string # We are only looking for calls with arguments. arguments = node.arguments return unless arguments arguments = arguments.arguments length = arguments.length # Get rid of any parentheses to get directly to the contents. arguments.map! do |argument| current = argument while current.is_a?(Prism::ParenthesesNode) && current.body.is_a?(Prism::StatementsNode) && current.body.body.length == 1 current = current.body.body.first end current end # We are only looking for arguments that are either a string with an # array of locals or a keyword hash with symbol keys. = if (length == 1 || length == 2) && !arguments[0].is_a?(Prism::KeywordHashNode) { partial: arguments[0], locals: arguments[1] } elsif length == 1 && arguments[0].is_a?(Prism::KeywordHashNode) && arguments[0].elements.all? do |element| element.is_a?(Prism::AssocNode) && element.key.is_a?(Prism::SymbolNode) end arguments[0].elements.to_h do |element| [element.key.unescaped.to_sym, element.value] end end return unless # Here we validate that the options have the keys we expect. keys = .keys return if !keys.intersect?(RENDER_TYPE_KEYS) return if (keys - ALL_KNOWN_KEYS).any? # Finally, we can return a valid set of options. end
#render_call_template(node) (private)
Accept the node that is being passed in the position of the template and return the template name and whether or not it is an object template.
# File 'actionview/lib/action_view/render_parser.rb', line 118
def render_call_template(node) object_template = false template = case node.type when :string_node path = node.unescaped path.include?("/") ? path : "#{directory}/#{path}" when :interpolated_string_node node.parts.map do |node| case node.type when :string_node node.unescaped when : "*" else return end end.join("") else dependency = case node.type when :class_variable_read_node node.slice[2..] when :instance_variable_read_node node.slice[1..] when :global_variable_read_node node.slice[1..] when :local_variable_read_node node.slice when :call_node node.name.to_s else return end "#{dependency.pluralize}/#{dependency.singularize}" end [template, object_template] end
#render_calls
[ GitHub ]# File 'actionview/lib/action_view/render_parser.rb', line 15
def render_calls queue = [Prism.parse(@code).value] templates = [] while (node = queue.shift) queue.concat(node.compact_child_nodes) next unless node.is_a?(Prism::CallNode) = (node) next unless render_type = (.keys & RENDER_TYPE_KEYS)[0] template, object_template = render_call_template([render_type]) next unless template if .key?(:object) || .key?(:collection) || object_template next if .key?(:object) && .key?(:collection) next unless .key?(:partial) end if [:spacer_template].is_a?(Prism::StringNode) templates << partial_to_virtual_path(:partial, [:spacer_template].unescaped) end templates << partial_to_virtual_path(render_type, template) if render_type != :layout && [:layout].is_a?(Prism::StringNode) templates << partial_to_virtual_path(:layout, [:layout].unescaped) end end templates end