Class: RuboCop::Cop::DocsKit::RenderComponentPreferred
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::DocsKit::RenderComponentPreferred
- Extended by:
- AutoCorrector
- Defined in:
- lib/rubocop/cop/docs_kit/render_component_preferred.rb
Overview
Enforces the kit helper form over render <Kit>::<Class>.new(...).
The docs-kit DocsUI module and the DaisyUI gem are both extended with
Phlex::Kit, which defines a singleton method per component class. That
makes DocsUI::Code(...) equivalent to render DocsUI::Code.new(...) but
terser and consistent. Adapted from cosmos' Cosmos/RenderComponentPreferred.
The cop keeps the namespace prefix (DocsUI::Code(...) rather than
Code(...)) because the unqualified helper may resolve to a different kit
depending on inclusion order. Keeping the prefix makes the rewrite
mechanically safe in every rendering context.
Contexts the cop does NOT fire in:
render <class-method-call>likerender UI::Modal.clear— not a .new.- elements of a
turbo_stream: [...]array — class-method calls that return Turbo Stream payloads, not.newcomponent instances.
Constant Summary collapse
- MSG =
"Use `%<suggestion>s` instead of `%<original>s`."- KIT_MODULES =
Kit modules recognised by the cop.
%w[ DocsUI DaisyUI ].to_set.freeze
Instance Method Summary collapse
Instance Method Details
#on_send(node) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/rubocop/cop/docs_kit/render_component_preferred.rb', line 54 def on_send(node) return if inside_array_literal?(node) return unless node.arguments.length == 1 match = render_new_send(node) || render_new_block(node) return unless match new_call_node, const_node = match namespace = kit_namespace(const_node) return unless namespace helper_headline = helper_headline(new_call_node, const_node) original_headline = "render #{new_call_node.source}" add_offense(node, message: format(MSG, suggestion: helper_headline, original: original_headline)) do |corrector| # Replace ONLY `render <Kit>::<Class>.new(args)` with the helper call, # leaving any trailing block (`do...end` or `{ ... }`) untouched. That # keeps the rewrite range off the block body, so a nested kit render # inside the block corrects independently instead of clobbering. range = node.source_range.begin.join(new_call_node.source_range.end) corrector.replace(range, helper_headline) end end |