Module: RuboCop::Cop::ViewComponent::Base
- Includes:
- ProjectIndexHelp
- Included in:
- ComponentSuffix, MissingPreview, NoGlobalState, PreferComposition, PreferPrivateMethods, PreferSlots
- Defined in:
- lib/rubocop/cop/view_component/base.rb
Overview
Shared helper methods for ViewComponent cops. Requires rubydex with UseProjectIndex: true for ancestry resolution.
Constant Summary collapse
- VC_BASE =
"ViewComponent::Base"
Instance Method Summary collapse
- #component_namespaces ⇒ Object
-
#enclosing_class(node) ⇒ Object
Find the enclosing class node.
- #fully_qualified_name(node) ⇒ Object
-
#inside_view_component?(node) ⇒ Boolean
Check if node is within a ViewComponent class.
- #require_project_index! ⇒ Object
-
#view_component_class?(node) ⇒ Boolean
Check if a class node inherits from ViewComponent::Base.
-
#view_component_parent?(node) ⇒ Boolean
Check if a constant node resolves to a class with ViewComponent::Base as ancestor.
-
#view_component_parent_class?(node) ⇒ Boolean
Check if a class node is itself an abstract parent class (has ViewComponent::Base as ancestor and has descendants in the project).
Instance Method Details
#component_namespaces ⇒ Object
64 65 66 |
# File 'lib/rubocop/cop/view_component/base.rb', line 64 def component_namespaces cop_config["ComponentNamespaces"] || [] end |
#enclosing_class(node) ⇒ Object
Find the enclosing class node
69 70 71 |
# File 'lib/rubocop/cop/view_component/base.rb', line 69 def enclosing_class(node) node.each_ancestor(:class).first end |
#fully_qualified_name(node) ⇒ Object
56 57 58 59 60 61 62 |
# File 'lib/rubocop/cop/view_component/base.rb', line 56 def fully_qualified_name(node) namespace = node.parent_module_name short_name = node.identifier.source return short_name if namespace.nil? || namespace == "Object" "#{namespace}::#{short_name}" end |
#inside_view_component?(node) ⇒ Boolean
Check if node is within a ViewComponent class
74 75 76 77 78 79 80 81 |
# File 'lib/rubocop/cop/view_component/base.rb', line 74 def inside_view_component?(node) require_project_index! klass = enclosing_class(node) return false unless klass view_component_class?(klass) end |
#require_project_index! ⇒ Object
83 84 85 86 87 88 89 90 |
# File 'lib/rubocop/cop/view_component/base.rb', line 83 def require_project_index! return if project_index raise <<~MSG ViewComponent cops require `AllCops/UseProjectIndex: true` in your .rubocop.yml for ancestry-based class detection. MSG end |
#view_component_class?(node) ⇒ Boolean
Check if a class node inherits from ViewComponent::Base
16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/rubocop/cop/view_component/base.rb', line 16 def view_component_class?(node) return false unless node&.class_type? class_source = fully_qualified_name(node) return true if component_namespaces.any? { |ns| class_source.start_with?(ns) } require_project_index! parent_class = node.parent_class return false unless parent_class view_component_parent?(parent_class) end |
#view_component_parent?(node) ⇒ Boolean
Check if a constant node resolves to a class with ViewComponent::Base as ancestor
31 32 33 34 35 36 37 38 39 40 |
# File 'lib/rubocop/cop/view_component/base.rb', line 31 def view_component_parent?(node) return false unless node.const_type? require_project_index! declaration = resolve_constant_in_index(node) return false unless declaration.respond_to?(:has_ancestor?) declaration.name == VC_BASE || declaration.has_ancestor?(VC_BASE) end |
#view_component_parent_class?(node) ⇒ Boolean
Check if a class node is itself an abstract parent class (has ViewComponent::Base as ancestor and has descendants in the project)
44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/rubocop/cop/view_component/base.rb', line 44 def view_component_parent_class?(node) return false unless node&.class_type? require_project_index! declaration = resolve_constant_in_index(node.identifier) return false unless declaration.respond_to?(:has_ancestor?) declaration.has_ancestor?(VC_BASE) && declaration.descendants.any? { |d| d.name != declaration.name } end |